# HG changeset patch # User Karoly Lorentey # Date 1134249508 0 # Node ID 37d0562504bfdd3455363352391fcc8d00f4ab11 # Parent 8e25aa911e3e4ff9071d11489974fa081cc20c17# Parent 13ebe78ad942048cde4964787aee53dbeed1782f Merged in changes from CVS trunk. Patches applied: * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-664 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-665 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-666 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-447 diff -r 8e25aa911e3e -r 37d0562504bf admin/FOR-RELEASE --- a/admin/FOR-RELEASE Sat Dec 10 21:12:12 2005 +0000 +++ b/admin/FOR-RELEASE Sat Dec 10 21:18:28 2005 +0000 @@ -48,7 +48,7 @@ * BUGS ** Fix window resizing bug: -C-x 2, C-x 3, C-x 2. Now try to move the bottom of the +C-x 2, C-x 3, C-x 2. Now try to move the bottom of the second window to the left. ** TCP server processes do not work on Windows. @@ -122,7 +122,7 @@ man/calendar.texi joakim@verona.se Chong Yidong man/cmdargs.texi Chong Yidong "Luc Teirlinck" man/commands.texi "Luc Teirlinck" Chong Yidong -man/custom.texi Chong Yidong +man/custom.texi Chong Yidong "Luc Teirlinck" man/dired.texi Chong Yidong joakim@verona.se man/display.texi "Luc Teirlinck" Chong Yidong man/emacs.texi "Luc Teirlinck" Lute Kamstra diff -r 8e25aa911e3e -r 37d0562504bf etc/ChangeLog --- a/etc/ChangeLog Sat Dec 10 21:12:12 2005 +0000 +++ b/etc/ChangeLog Sat Dec 10 21:18:28 2005 +0000 @@ -1,3 +1,7 @@ +2005-12-02 Jay Belanger + + * NEWS: Add comment about the Calc prefix. + 2005-11-28 Thien-Thi Nguyen * MORE.STUFF: Add entry: "Go in a buffer: Go Text Protocol client". diff -r 8e25aa911e3e -r 37d0562504bf etc/NEWS --- a/etc/NEWS Sat Dec 10 21:12:12 2005 +0000 +++ b/etc/NEWS Sat Dec 10 21:18:28 2005 +0000 @@ -268,6 +268,12 @@ to the text before point. If there is text in the buffer after point, it remains unchanged. +** When Emacs prompts for file names, SPC no longer completes the file name. +This is so filenames with embedded spaces could be input without the +need to quote the space with a C-q. The underlying changes in the +keymaps that are active in the minibuffer are described below under +"New keymaps for typing file names". + +++ ** M-o now is the prefix key for setting text properties; M-o M-o requests refontification. @@ -1526,9 +1532,11 @@ ** Calc is now part of the Emacs distribution. Calc is an advanced desk calculator and mathematical tool written in -Emacs Lisp. Its documentation is in a separate manual; within Emacs, -type "C-h i m calc RET" to read that manual. A reference card is -available in `etc/calccard.tex' and `etc/calccard.ps'. +Emacs Lisp. The prefix for Calc has been changed to `C-x *' and Calc +can be started with `C-x * *'. The Calc manual is separate from the +Emacs manual; within Emacs, type "C-h i m calc RET" to read the +manual. A reference card is available in `etc/calccard.tex' and +`etc/calccard.ps'. --- ** The new package ibuffer provides a powerful, completely @@ -1744,9 +1752,9 @@ can generate a table source in typesetting and markup languages such as latex and html from the visually laid out text table. -+++ -** The thumbs.el package allows you to preview image files as thumbnails -and can be invoked from a Dired buffer. +** The tumme.el package allows you to easily view, tag and in other ways +manipulate image files and their thumbnails, using dired as the main interface. +Tumme provides functionality to generate simple image galleries. +++ ** Tramp is now part of the distribution. @@ -1997,6 +2005,54 @@ +++ ** CC mode changes. +*** The CC Mode manual has been extensively revised. +The information about using CC Mode has been separated from the larger +and more difficult chapters about configuration. + +*** Changes in Key Sequences +**** c-toggle-auto-hungry-state is no longer bound to C-c C-t. + +**** c-toggle-hungry-state is no longer bound to C-c C-d. +This binding has been taken over by c-hungry-delete-forwards. + +**** c-toggle-auto-state (C-c C-t) has been renamed to c-toggle-auto-newline. +c-toggle-auto-state remains as an alias. + +**** The new commands c-hungry-backspace and c-hungry-delete-forwards +have key bindings C-c C-DEL (or C-c DEL, for the benefit of TTYs) and +C-c C-d (or C-c C- or C-c ) respectively. These +commands delete entire blocks of whitespace with a single +key-sequence. [N.B. "DEL" is the key.] + +**** The new command c-toggle-electric-mode is bound to C-c C-l. + +**** The new command c-subword-mode is bound to C-c C-w. + +*** C-c C-s (`c-show-syntactic-information') now highlights the anchor +position(s). + +*** New Minor Modes +**** Electric Minor Mode toggles the electric action of non-alphabetic keys. +The new command c-toggle-electric-mode is bound to C-c C-l. Turning the +mode off can be helpful for editing chaotically indented code and for +users new to CC Mode, who sometimes find electric indentation +disconcerting. Its current state is displayed in the mode line with an +'l', e.g. "C/al". + +**** Subword Minor Mode makes Emacs recognize word boundaries at upper case +letters in StudlyCapsIdentifiers. You enable this feature by C-c C-w. It can +also be used in non-CC Mode buffers. :-) Contributed by Masatake YAMATO. + +*** New clean-ups + +**** `comment-close-slash'. +With this clean-up, a block (i.e. c-style) comment can be terminated by +typing a slash at the start of a line. + +**** `c-one-liner-defun' +This clean-up compresses a short enough defun (for example, an AWK +pattern/action pair) onto a single line. "Short enough" is configurable. + *** Font lock support. CC Mode now provides font lock support for all its languages. This supersedes the font lock patterns that have been in the core font lock @@ -2016,11 +2072,10 @@ variable font-lock-maximum-decoration. Note that the most demanding font lock level has been tuned with lazy -fontification in mind, i.e. there should be a support mode that waits -with the fontification until the text is actually shown -(e.g. Just-in-time Lock mode, which is the default, or Lazy Lock -mode). Fontifying a file with several thousand lines in one go can -take the better part of a minute. +fontification in mind; Just-In-Time-Lock mode should be enabled for +the highest font lock level (by default, it is). Fontifying a file +with several thousand lines in one go can take the better part of a +minute. **** The (c|c++|objc|java|idl|pike)-font-lock-extra-types variables are now used by CC Mode to recognize identifiers that are certain to @@ -2035,10 +2090,11 @@ language, so it's possible to e.g. turn on Javadoc font locking in C buffers. See the variable c-doc-comment-style for details. -Currently two kinds of doc comment styles are recognized: Suns Javadoc -and Autodoc which is used in Pike. This is by no means a complete -list of the most common tools; if your doc comment extractor of choice -is missing then please drop a note to bug-cc-mode@gnu.org. +Currently three kinds of doc comment styles are recognized: Sun's +Javadoc, Autodoc (which is used in Pike) and GtkDoc (used in C). (The +last was contributed by Masatake YAMATO). This is by no means a +complete list of the most common tools; if your doc comment extractor +of choice is missing then please drop a note to bug-cc-mode@gnu.org. **** Better handling of C++ templates. As a side effect of the more accurate font locking, C++ templates are @@ -2073,14 +2129,9 @@ are normally placed under the start of the respective pattern, function definition, or structured statement. -The predefined indentation functions haven't yet been adapted for AWK -mode, though some of them may work serendipitously. There shouldn't be -any problems writing custom indentation functions for AWK mode. - -The command C-c C-q (c-indent-defun) hasn't yet been adapted for AWK, -though in practice it works properly nearly all the time. Should it -fail, explicitly set the region around the function (using C-u C-SPC: -C-M-h probably won't work either) then do C-M-\ (indent-region). +The predefined line-up functions haven't yet been adapted for AWK +mode, though some of them may work serendipitously. There shouldn't +be any problems writing custom indentation functions for AWK mode. **** Font Locking There is a single level of font locking in AWK mode, rather than the @@ -2088,24 +2139,16 @@ idiosyncrasies in AWK mode's font-locking due to the peculiarities of the AWK language itself. -**** Comment Commands -M-; (indent-for-comment) works fine. None of the other CC Mode -comment formatting commands have yet been adapted for AWK mode. - -**** Movement Commands -Most of the movement commands work in AWK mode. The most important -exceptions are M-a (c-beginning-of-statement) and M-e -(c-end-of-statement) which haven't yet been adapted. - -The notion of "defun" has been augmented to include AWK pattern-action -pairs. C-M-a (c-awk-beginning-of-defun) and C-M-e (c-awk-end-of-defun) -recognize these pattern-action pairs, as well as user defined -functions. - -**** Auto-newline Insertion and Clean-ups -Auto-newline insertion hasn't yet been adapted for AWK. Some of -the clean-ups can actually convert good AWK code into syntactically -invalid code. These features are best disabled in AWK buffers. +**** Comment and Movement Commands +These commands all work for AWK buffers. The notion of "defun" has +been augmented to include AWK pattern-action pairs - the standard +"defun" commands on key sequences C-M-a, C-M-e, and C-M-h use this +extended definition. + +**** "awk" style, Auto-newline Insertion and Clean-ups +A new style, "awk" has been introduced, and this is now the default +style for AWK code. With auto-newline enabled, the clean-up +c-one-liner-defun (see above) is useful. *** New syntactic symbols in IDL mode. The top level constructs "module" and "composition" (from CIDL) are @@ -2114,8 +2157,10 @@ composition-close, and incomposition. *** New functions to do hungry delete without enabling hungry delete mode. -The functions `c-hungry-backspace' and `c-hungry-delete-forward' can be -bound to keys to get this feature without toggling a mode. +The new functions `c-hungry-backspace' and `c-hungry-delete-forward' +provide hungry deletion without having to toggle a mode. They are +bound to C-c C-DEL and C-c C-d (and several variants, for the benefit +of different keyboard setups. See "Changes in key sequences" above). *** Better control over `require-final-newline'. @@ -2143,10 +2188,11 @@ In some cases there are more than one position given for a syntactic symbol. -This change might affect code that call `c-guess-basic-syntax' directly, -and custom lineup functions if they use `c-syntactic-context'. However, -the argument given to lineup functions is still a single cons cell -with nil or an integer in the cdr. +This change might affect code that calls `c-guess-basic-syntax' +directly, and custom lineup functions if they use +`c-syntactic-context'. However, the argument given to lineup +functions is still a single cons cell with nil or an integer in the +cdr. *** API changes for derived modes. @@ -2157,7 +2203,8 @@ Mode with less risk of such problems in the future. **** New language variable system. -See the comment blurb near the top of cc-langs.el. +These are variables whose values vary between CC Mode's different +languages. See the comment blurb near the top of cc-langs.el. **** New initialization functions. The initialization procedure has been split up into more functions to @@ -2207,15 +2254,15 @@ **** Better alignment of line continuation backslashes. `c-backslash-region' tries to adapt to surrounding backslashes. New -variable `c-backslash-max-column' which put a limit on how far out +variable `c-backslash-max-column' puts a limit on how far out backslashes can be moved. **** Automatic alignment of line continuation backslashes. This is controlled by the new variable `c-auto-align-backslashes'. It affects `c-context-line-break', `c-context-open-line' and newlines inserted in Auto-Newline mode. + **** Line indentation works better inside macros. - Regardless whether syntactic indentation and syntactic indentation inside macros are enabled or not, line indentation now ignores the line continuation backslashes. This is most noticeable when syntactic @@ -2224,10 +2271,10 @@ *** indent-for-comment is more customizable. The behavior of M-; (indent-for-comment) is now configurable through -the variable `c-indent-comment-alist'. The indentation behavior based -on the preceding code on the line, e.g. to get two spaces after #else -and #endif but indentation to `comment-column' in most other cases -(something which was hardcoded earlier). +the variable `c-indent-comment-alist'. The indentation behavior is +based on the preceding code on the line, e.g. to get two spaces after +#else and #endif but indentation to `comment-column' in most other +cases (something which was hardcoded earlier). *** New function `c-context-open-line'. It's the open-line equivalent of `c-context-line-break'. @@ -4156,6 +4203,15 @@ +++ ** Enhancements to keymaps. +*** New keymaps for typing file names + +Two new keymaps, `minibuffer-local-filename-completion-map' and +`minibuffer-local-must-match-filename-map', apply whenever +Emacs reads a file name in the minibuffer. These key maps override +the usual binding of SPC to `minibuffer-complete-word' (so that file +names with embedded spaces could be typed without the need to quote +the spaces). + *** Cleaner way to enter key sequences. You can enter a constant key sequence in a more natural format, the diff -r 8e25aa911e3e -r 37d0562504bf etc/orgcard.ps --- a/etc/orgcard.ps Sat Dec 10 21:12:12 2005 +0000 +++ b/etc/orgcard.ps Sat Dec 10 21:18:28 2005 +0000 @@ -10,7 +10,7 @@ %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips -t landscape -o orgcard.ps orgcard.dvi %DVIPSParameters: dpi=600, compressed -%DVIPSSource: TeX output 2005.11.24:1542 +%DVIPSSource: TeX output 2005.12.06:1143 %%BeginProcSet: texc.pro %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S @@ -352,210 +352,207 @@ CCBD1F58ABBF1F53AD21E3BFF25EEEB046F66A924E5F431EBD7228050BE2DF43 0B9B538DAAD511EED97630CD9A9C05CC49DC251325A93EA842C6D07B44BE620F 08E66B611F54314B0177E299304F2294F8DEDE9914736944F125A50B5007373E -588AD80D9983CE7824DA30CEE5DC3114D69D7ACEC0758D8201805B82925EF3C2 -C87A1A169C5ADE44B561EC1660E617FB39D1B1547B33C0FEB33C3A1D7340A62A -CD9CEFA49481F19B39A704A53A0B98A11744143CDDA0E668E6325935C6497A9F -AFF471194932AFECBF25B441AD55A43751FBAB76F3E544C4254AEC4BEB5CFE4C -C1318C3A0FAD0E8C1BABEE20B203E1DD9412E66BC55BEBD6FBBEBA84F56604FD -85D50F733D9794611F4137EC10ACB4C4ECA5A81CAACC45213E92ED3C26726BBE -91430E7633A2BDB8EA3D0C55259D7DBE468AC0964A63728C9B8EA4E15CF0EEA3 -2E754B9170EAE6B8818DCCDDAD643B9F6C91C3C5B245CD442358C60AF390DC76 -342E659D4EC45552626F069F346F46B18062CE26D5912336C6B29FCBFA5C3113 -ED86E44B529CD95B7B5B934D899762C4F3457F56ACCC763BCCD5BD08975EB5F1 -C5216DA4CBF3409EC71054B0145183F7DFB31517D199EB16D4C6DB0AF05E5720 -10B06F395BE3C8C59CEEBCEA1E00F9EA3FD880AC197508CEC11E33B6B6EABE3C -0FAEBF246743F62D280875D052656696AA88DABB918F793CB2994A1ACCFA0CAE -AF6FDDF489109DEF07F93B5B0078FC5FD9829DD296F62F23400F5DD6CB096557 -EDA737413C744FDBB0615BD40A79EA2929EB7AC767E58D886B310700733D2895 -3925911133631F28291974294AACF4A35F92A5E5262DCF33810A6F9C51E9D141 -F84B0C26B5ADECB44B646C79DD1C656529B7122739C0459B2B47A2C357EF9A36 -2B376DDF54F1F4F133419EF14CCC6010D360DFA8A7B122FFC5A4C560ED184F16 -057D3F76B6B2E935B31B17FC4066916FFBA0B9AFF287D251985AB3FC3D0D7E9A -91F094356B3D6CDBCB2D74A3FDE23526B22C223EA35C9E5054053B23AF004324 -80F023FCDFDFA6B8F0E03A799D87FC2690C5D1ABB9C52B03402E37309091A1FC -1D66EB48FE3E4BD326AA65839A9A7276C876F8079C11F2F3A7CBFDAB5AD3D4A3 -8377AE4862F390039E3FBE5D79B5318774B0A9B1321AAFCE8E87568C0AD0E82F -D4DCEEA5DD4EFDB2E89D336174E76036DA08DE4A26FC63560057B87FDE9E060A -3AA30E1B447B1E8EF31762C0998DF24B2860CF8B589FCE1050CC259171420306 -F4DAC090E032E4C3E0DD43305541155C1EB135B2093F7E23106387AB7A3DA0E6 -1A835F6D058227003A8C974907CC073F2ADE33AA774165BB24381E65DF19FD6E -F15BB66BBAB0129C79A80CF32E542B68FFAD1BCBF6A4D867933FBBFA82771E7F -1B2E677040596B7872A038FF8F23511C33E23D362CED5E303736D1CA28D78AA2 -20701B83020AE62003DC59413C6A2413C593CDC819644742F8CDF60D541710C6 -5A23FFCE6F6CF6AE26953CA4F01A62D6F7DB8F122B30506891DA023D16E56BE4 -84D72EC9DE3B16197B3BF97EB8A840BD2C17861583477317DEA062693B2EA959 -5F5233B416B4E1D63C6014BB96D0718DD9D81A885793F315402E91C274122E5D -96AF9A05E10DA6276A33E861C006807BBA6B005583CD961491D5F183B62EA558 -C50F25F2F6B211BD3723FF98E01167C48C0A6CCEA0477895D21519AE86FEB4D7 -47C77202688775B4C86882C20D24EBF7AC98A3B9BCBFF750433E17824A4425C5 -7444E5201F1313A4C9FF361FCD9ECB1597C1F0605FEA98DD109C636433920603 -6671529E0E7AE2EC8A7D196FCA784D3CD2F88190B3F150533BAF3CFE15247D01 -864A2552F602D65088AA7F0D87C02768D8FA62930E18702F98558982C5A202AC -111C6B0359273116F1DF9E5610AC46B99995425144D1352A881C79D9E0042850 -B51B2375DA55C34A47510C7D7435FAE7D391BAEC1F8BC0C93B866E7CE261384C -6B277C66E817BF006B636AB133309384FE0985DBC34190E1E1ABB3A63892361C -9970FC5732C7A4259809EEF348E6D3BC6AAB5BB012A098A02E33F9BDDA250A8A -421EE4EBA46B82C10A5A6ADB2390A7B363CF16A0FFEFAAD7F6D2A80FE4720095 -BD78A6E4B95D6FC7DA4196E61C5FD0F9F37537E6BA581496E38625EF0B7826DF -F021663E6D5DF3C93C5EC2C5B510867ABFC5404F490C683337EE7B22D3CBE7DC -8EB4F9F2C25034C8779010A6835ACED2B05B9CF9753760A803073509C71A6372 -3634DB39F894B6EBAA9A34511357F3C106E42E9A6A592C1B49BB0AF668C95448 -9E0968CE39754452648068F82C53CA2ABE392713979634E7DD66819E7B3FF5D3 -A8890FA876857F4560A44029389A6E425ED8DBB25BFDDCFB510C071414760191 -A36723D251F10830B03E21B6FD61C1E92BD630B5EFD283AF248DA69C537D6F0C -1CDC58032A7A91E836FF66810D886A73453A28044F55F754CD70A9B3EB5D27DF -51D6E57085AC4487C5D015FC51F840F7DBB1733500062C608802C556F8A4623D -0F94B67BC91E07FC2AD7E067F3C033E53216804B7371498113125A8CFC63D450 -4760B98ED1397A8862A8FA5D13923D22ABDF48B7F502916EF7C7D6BC52EBA5F7 -AD95E37E4979B7417C8C0E2599E4BB85883AF9E9A3C9DA432859AF9C909DDA53 -8ED9C0B3DC6BF49C5FB81780078209D21E6B54A8E669212B6E3569B615502ECA -D67BC610E59409178B640ECD0A125371ECAA360FDD5843892BCBD22BF4D640EB -99515496E12E2C68567610FC8F6E03C176D14B692A9A23BE3B50C2EB30BCE5F4 -481500B293CA54AAE5CA0A85C221493792B967423418E870C4DC7344E07A7E52 -1B2DED4C2FED4C602DCF37065FEE9BDE6D1FD95FEC1F30A5E3A1833B09E6B1DA -D6A41C57493D4C1D8D87C8BE2443D2B917A0E3D26C324CA101E84369AFA73586 -E499C3627661DCFABF7478DCEF651E33C666957BE759F9DCB9F263AD3FA48BBF -B47A84A914CFD8297141FF5AD0186753DADAD79315D14C68C19305D73DE6E4DB -56BDDF037DA982E956F9C3B554E0746178294ABF6F46D1669D1675AEB8C924EB -F9966956C8AC25940640B8C9DE9A76B36D04806A918FB4F7160503031AEB7DD4 -61C04BD3F6711F09EC71FEB6EA3904FD8AF75054659ECE0DAAEA1A614AAC6574 -9098FB7BD891E65552583AA519C7E4F9E6B5531B2215300CB262F42763BFDF5D -FA2E6EB7E7F6585C80CD880ABAE340087A781C7EABD56C59A14EC17920FA7AE3 -049BA2DE8D5BB77ADECA23767F842642B7C0CC9AA177990CF0DD00A9DD8458CA -5506DD3A5E5BCF2329047F560F0E30FCA7CA304594B738A0C7C70D8FE364AF59 -620E6527C061B6FECEBEEF0841969656F1A7A27731338B640A3AF243F58FBBF8 -E8ADA1CCD8DE701243EBA2E1F44C732143BFC4FA89B24B3B473CDC022111D477 -ADDB77AAA600B6C6948133D05EF0838BD1E1EA1C747BDBA8A0BBF92DADE753EE -9F556D938E16961C2D13E7534B2B5F9EFEB2AFD65FADA831E81237BEDE73F7FA -B076E562E08D57555B3830834B64E4C1E0E1F89D9A5BFB959032106B1EFEE431 -DC828EB4EF66DEA434DAF191E92F1EFDC31954D055DDD87B1A2762DAD6AE5994 -322DC4FA2FCA4AADC293158C75900C540BC85384340B29A4B25F486145C311D0 -4296CA91BB16569CDAFDC9047D9FC8C26792828DD3CA18E045A2F9B473491501 -CD3ADB57FB1D94C1A0353861EAC98E1630E14BEA6DFB04A5B3FAE97F4EA3C792 -2C9ACBF61A5C14605AC9D0DA7E4D9904C6C6FDFF564723FDE4E72413067055C7 -22946CD598266AE7FBC63FF62068CA4F40B80C8EF9961503F7894AF2A392B595 -376F0CA48B4B23AB7112453DA02274095741C7102733C553B6EFB43A6E1DB0AC -C320C44357C4C7E98B96B30D9FEE86B7083080F0B6262FD69E07557FD018C1E4 -2CF6A276E789A63A9CEBCC8867E12C60D78B81F7C1AB5592E4AFE1AB1C8ADF1C -FE8A4773FDC6FC01BF698E5D46B4282983FF16F028D14104423D07047AC7003E -6B5CD6FC2D30DD0E6162498FF67D4091D68AC65A4658215B845AF706F4B74262 -C3A28732A7E1E786006F544853CCCED8B530ECE3460B11E11CC87B22DC0AB93A -AB7EC47BCE2BAEF0FC23C9A15C0D421D75AD13D931B8669F1018A207D8C57228 -028FEBB6453827DE33B1CDD0527CC4815CA2CF05CDF4735A1EFB79DED9AA8AC5 -A074DA91B9B860EE88F5269AC4C604DE488C269959A108FC5175637DFFB08DBD -2AE093CFF20E15AA2624D8E2A141EC3290852E27FBAC6BE21B65CD8036221193 -9967C4A6AD631F2374582F8DA277621961DE7EA41FA110782DD3E1E7CFC51058 -C961948FDBF02A2E7BF0A299EE696F0B98A0C4ABB7CB67AB28A2EF50D3D212AC -1C51DF3909E484FC3430FF1AB2CD9CE667A9EB489A981A9A02F8F999D9215F5A -DD609F5DF9519DA3410867680942AAFF2275D255709997653E88CB23D16A110D -C5C65DC18750D868C8F60E64265C81DD7CD7C2036D13532E3DC7D12600FAAFDE -EC32EB7989458A220339D451A25E3C4B2D52D265875F06465C913FD75BA30285 -AC61B32BD2C307FCBAF38E14FF6A64C6A5C874A2D7DFE3025E3CD30BA9C60D89 -00BE5411544E97D9791949722F76A99D549D344BC1EB88C9B8BFEB74EC94D190 -F5DE00D2EA0003DECDD4FDEDC0834053AFE3EFF04193E360460A286794D02FDD -A174E3CE72C69D32C7C4EF33B97CAB2929A26662E4E3C2313469ACB6BD21CAFD -8C81FBAB0EE7C26BC5B40AC9880623CB5D595A4351BF7848CA3212D74AE449CB -35BE1BE2C6C795B56D2731C0BC9C5DBCC652F025212C35C50B3937212871472C -7B6AA7AA075FCE6068BCF7474EE3FCA088733439E5AB06D78F62A574157DFCDC -43990D8A9673300AF0D2450C2B9B9000BDC9C4A5CE57764A7236370458E8A0D5 -0D777DC1156A9D82D070FFE0DEA2DED3854CB7A09FD34F1B3513821C26FB6F6E -F3BA660EBB0C08D8B976CB89B4E05C95A20EB2F74F4C1DA67E783E9C936A749A -E20866E646774E132A0A12BD5907BA8D7FCBACC83004895110BD65223C4A2821 -02C709F5A8E1E9EE3C0C2430D6CDD4AAC32F45093EEB1AE961B1BCAA823E7F55 -0B9E5614DF4B2703532E2260B70062E33F40463B176D7645168DD4AF226B39E5 -8B74BCA01988FCF9475B9935412016704A09A331365D2E745E778331ACAED5E9 -AF662A9D5C7A5FECE76F73EE20E2BBD0647304E75161347291906E7ADB3F2446 -9769F36EEBCEC59167199793122D96428A44A2D8C9B704802543B0569C140134 -8F180AFAAEDC8550B566E6D460544DB84402A9AF79D8A315C53FAFA3A5898B26 -CF8D7EAEF6B7E19B9DDF927B7DAEA9249FFF69872A6C3F4289546E6969D29360 -0A8684B1D5025DDEBF2554248AF53EE9D53F9412CA89F004911834BE96221C1E -8582F51F1A345ADAD0537938A96E73E35063A2207FF7FFCC55C9F7AEF734D089 -A0693D41848236FCE67E85AD5372C73B61BF5B58CC2D9616FB78144198E65267 -6940C7E3E3381C91C877B7F78B4747F46D12CF347E20C1A2A78BFAF96C42D81F -16715D7E1FE7E671242791DA7D84D5D885F905093969F3836299BF6874A8B12E -9E1F3A05D940BFABFDD7D3085AF8A4FD01092C88CB75F4060BD85F2F958DB0A6 -64145DC3DCA6903E0E018A7594BD7114F336D12C61AE4E29138A0165FE21BE5C -C2F4B9D496ACE81861919BB69DC06E5AEABD3F5E5BDFF3F507BDA4E366BDD481 -05558CE1213A6D28CC2D5D2E5265A754141E312F42B64EA2D51C79C71DA5BC92 -920821C437120A19F9EA3BC48F16073251D458BA53C4C7DDF0035ABB32939C11 -4842DA0E489C7C2025B432B66352C56D78BB8391DA79E75DDEC29588C596BB4D -67EDF9492B91B83D9F1F26444094D60329A5D3F1BDE976DB2E71B6E4CA9B8EA4 -BF43C91A16A2D9D23E5448C2FA38B8D24D142549E45572A29655C9BD31755718 -A58C3DC4964C0B49791F36809863835CD8E4B196CE8D18D714B2B3AE2BE90C4D -65C1210B9E3A8F248BAFB0CC5579302F6FC26FC3E197076891FB758B0595DC4E -7F1EEC99FFB654D46736BCE43BF37DB7681CF7655DF55592B7A494EA541AFFC5 -CE5815E1D989D9E1CE87E116DA4BCB7E16AFAD2327C434AC71EC756B96476BBC -0C997DC8C439E839EC939B55BEA698E3435BD911258234B6993B3890077DADCA -4DE92B37E94166A24DABCEAC3BB808557FE09FAAFD6DD316F44952A6710B4824 -6F5B5D4AE9F8A14DD207DFB697D5DC67FC3EBAE49A1A339525ED5ADBFFE58333 -43E8AAD4030869427226950AEEBD11A07815D9C3BBF2570A51D6C0249CCE9026 -B12ECEBAF112069547DBD47B7C8869523AFA7177F6E87F534A5425693DB8AD79 -497B95A90B056F61B6B4A89A7BB23B4F93BF5DAF637D71DDF4F48E34CF347EB4 -12173D9A72526C9B561F6CB2C3D43B0487E09B2C7B1822E9CF5D2D3836553AE5 -5A71793EFB52216CAA4948C203E1EA410B3BA72B6E2059AD04B5ADF54B6A5BD6 -33EDE67267334D9170FF9E7F9802516295D91F1A63EA8433F696E3565EBDDB1F -1055025C16B5EB6708479CBDE2188D8371EE8863CBCD8533DE37E0242842C0AD -114045C8B131BA3790146335EE07690C8DCAFE2F61824BE4F109F33486663D45 -24391006E700052BC8E90098BE7B5F13EF5412DAF6BDF0DFE9775FDC185369B1 -C53AAAEB34A9727AF997415595F8EED263C0B1B9448119E705396F6143E8276C -C6C586E5FA8FF1C6B701578D1399211EA9398DB2A6397F68C7B7E0B6434DD516 -E4F039207D1BE48AD5F63C3E804C2DCEB39E97DA8D1D6E8C73180A916D8923FB -5EA2430412C28ADEE42F3B6390ADD6159BE501FE3252B6EDE96AAD8035E2C8DA -B00C25B07488F2BCD84508719DA8D309F8191B86CDC22E73730C9C91B7CD6062 -86032E22F92B948647A3351A31DABAD5F5F8D2C9911892C359471026AC047E49 -BFCC10C17712C6B7123EC9FE3BDF0ADFBA2BEC0A69B18DA231B43BE20694139C -D6C856E3B7C6907F8BFEAFD753BDD5B50F8B25ACC61C778FE96B229CA7F891C6 -07EAA8551B790D6CAB23C80436A3E2A7F24FE4CDA84AB81AF8D4105E2386F3EF -D77DD83730332F0F4B176E0C4ABF39ACC995CE3EECCE76C6363557C08F0DC723 -5E2B680D852174AF6BADB73DAF19EB4F921AC61E1FCE16EACABEB591173F687A -DDD0909654D7A243F4105F8201B6343221DAA1589DB4C496C1F702E0BD3CE68D -75071205B4D8ED2DF85276A3E53AAA46573771E0868482A2BC805C6A9D6C5480 -E23F690D6FA9CA9600A9F42F7F0EC92853C8FF64E2F137DB193543F78356EC5D -A090542039B0501650B6184093DDA5CDD52B6F8CE4460AC781C2F93EA339F10C -4921774575EDAB301E387C5A9200679ED86127611043364A319CB0C68B6FE176 -B0BA672AB3DE3F2B14A9E7C8CEA1DF76C716FD53CBFE583D1D0D20D0062A3DE2 -689408AE3D527703C591BA8C9982607CC08384A1049A1B328846A719FCA05D38 -087619AE510325FBDC54307AA468827EC8D84A19376740210EE95E5844872259 -7E2A055BFDC40D3C12946ACFE8CF26095719C3E10670A10417679DA5639B4175 -9DF86246392C78E114D745B9FCBE5D4D33E4E5935E6D4EB9F00F408045AAAB98 -47E445AE32BFAFF24107A37EDE0E9BA08934370E212F39035BA2AA51E2D711F4 -6D7215A05F5AD11422C9E8F65B80405D29CCDEE79165F59EBED93F9EB264792D -35F8C1FD095F18511EB516DB40AC15B6045D2A24A2B910EF3A632278208A0D66 -E19963591F45FD61AC0183CD5D4C5C1C8D69020874EF6079376801145636901B -D9EA1E35EF1E6B37D257D5B90862CED7C0D1F1B32C5324A28716EAC93B556BE4 -C2716C85ACD7AF85D52DA2E33312C42A6B7F28797BE80102E37B7F9C933BBE85 -121C64FCA542C6D5B7FA7FCB7CD0C41295625FA2D99E6FFC4D08450EE7C1EE81 -BC356927FF6F5AB869D083929EC1A643515702F602AB140A410378A65A721DE8 -1BE9F270589F468D5D2003FAC662A907296302C873DE919466A128FBECF122AE -6259456457D21A217D359EFFF23758BB537BD97472F22EC4EBE932F762884EAB -5D59AAC0097E2EE5A9EF77B1E0376AECE3AA529E5E518A24569007F5DB2F27BB -776BFF2348E9B2E9AB0B07B9BDBCA49E37E11E2980754CEF43ADCBBF32B9575A -C611F4AEBEB5A718524AB25FEA08E9E913E24FD94AB4E2E4FEFEF29C7A70055B -5FA0FA771D485CADF65EFFDD9B6897F675598532D8E974CB042BC7DD6B5A4B99 -F5D36E27D80AAA8417465223649E44E28D5AFABE693265DED4FE7711BB4BA083 -DC71244042798FE7E1965A469B8F8202DEB7C563F43A7E17A088FA36180AEDDE -345A2D7705A5ECEE8E305218791D9956DB2E848E422291D7E2E249329246BE92 -892554EBAC59949D310F38819EDCCAB09F4DCB80144604F8F1F43447138B311C -FCA400AD225FEF31D3B0F6A5E8DF91E4FBC39C93DDD11A2E54D1B8ECF5F386B8 -FD0DA95AE3E981FB36D9FA0344D6D41CCBE8F2320539411FA23360B88ECB4D38 -FADCAABE8049B06887D053FBF3ECC8A89BDE4A9F1ED7F6629866FA14ABAA2924 -9BDB9D6C93F6080593A4BBC0CE2567813B2AD04C99FB09443A684E644BA51B9E -9480AE4AB2148A081F6BCE154261D4B0F03864C6F79DBD622EF471A844048766 -6A872C8E99A82CB468B6FA50260CDD90B81CCB48A6F3BCE3865AE56A86569E23 -16B13DD6114D98293C0DF2585F4E2D01E5EC8E43DD6FFE027E2F0C9CC360BE2B -823DAB713978E73D7AA80DF69CADA74D8E23D902B9DA35EA2BC9D03AEF265D54 -79E86089AC4E8312FB9CE325D8DC9E4DB22BC048CD1F0EFCD64E62B785D97685 -6A34EB62E657BB2F3658B1EA87B4C07C45C8D8283BD35634EC67399AB00AA2F4 -A15A723E8EF9AD000007ADE862D7ADFF32A907D40BF9491FE05BCEADFDB83187 -2825ABF2EF18608411F9E31C3306B37E245F1571155D5651BA291AE16EBC0390 -FEEF8EDA9B9EAB02F1D3BABA0C4DE4FD20FEBC2DDA743FA0C32F7A746FBFAB22 -27B2B8547359B5EC413F98024A5574F48349213502D0F1C71093EF2AF2A7EE88 -67332DDCB9D9652B705E9D2ED1BEF1B9699D84F9B8520DDE2609F752E8D77F8D -ECF010C2F18EA526B4E2EAE1694834494990A4AFAF57286E171E4053788F3B2A -B7A2DDF04308E47448A06C66E987C2BEE43B5FD8890A1E11FCF4E0548E201941 -8437B4BC7A92174B7D5D8F4E9E98F48779968F00803F2FF59B1764EE197873EE -D1DFF6B12B54459FB5A6864CA9D73B89ADCBDBCA2DAAD3B42C4A9175F503F21D -C48D5145E2C6AA7D7FD787BC0D +588AD80D9983CE7824DA30CEE5DC3114D69D7ACEC0758D8201805B82925EF3C1 +3A6757674B84D9B585F981DDFFB42163EADF90346248E014A74E3FB3E6276FC1 +B4289FCDB4FDBE9C70CAF38E410965A3610F649DF8F81C73B87FBE27D44A3CA6 +D7883821CA22795E3EED184F4F59AC687AC06DC4DE7FD098E0EA61C494A5E960 +643D78025B1D18B4B7FBACCE2DEA453E35C08A6AC093F45FA0B1DE132F743CBA +75F2E7BE0311132C0E63C69D5182B98AEFC610F61D1E1EA51120D8A9F5DFFA8C +37C0ECCA2120E1DF7A551343BD7573FA24144A8D59CA684FF9FCC1E023A3401E +9797D658E92CED2255A273E429FAF43B0355E27EC83974BA4675520B2DC70DDA +DF783452C679BB77759479CB02FF3377BCCD8580E3D87D34CD579AA3F89AAB44 +E526EE761B0D371E27B5A02A5C494C5169651FA79795D332045B3E7F2CA100FA +FA8ADA74DCA851DA1BC7531E58EE08FC22F2F35E94D5DA013A4C9669B2825D26 +021982566B4347E518E82602B0CE5CBA1CD38E8B3CEBBFDF9E9811C896313F37 +51D5F7162441E4B2DF18A7A34326114950BE85B3E5AB465D54652575AAC03DF3 +E50E9FE8D184D33534E12AB92DF20BD72DC129A86CCC24981FF82E297D0B0F9E +0B66137443B501B5FA711C7DF380DB1F64404DA241D1EF5F2D012A0293405302 +F828BF879F46962DFAF75F44D4A394DB9D42E4874477097FF6F8DB9BC8712BC8 +661A95A2467073355FE697CBE1D8E298569935E5405C22555C40DB775A808F54 +642939D8E4F76C61B2FE966F4FB55319873127C8EEB0572023C36D7624E7B0B4 +EDC15EC6E697D900271A4A20C5D357ADAA313C4F7717EB32258DC6C8C298109C +B80F85F201C0E5366A259304EF113C9C4DD3110BC88F76744C8337B201E8D546 +E69D1328A06F23255AF9F6AFEE6E17FB36B75C80C4E1AE1BF7CCC3C779B3264C +2185266C84CBF559883C6074F8B71BB04D8AE260EDBB86146FBF41E6DA64FD10 +D7982F9EA6A15D7FB61FEE3CA2E4571F8FE6D37967776E22C71C0ACD260DF10B +255BCC7E8521B60EFEEF9529B5D4B5A5B366EC9D4E55342297E4E6BDD3B4A6E2 +B929A4F670CF051869BE77438C78DE9DA89764614B1F6E76A331BBBAAD3EAB0B +66E6D4F1564028019F420E47804B4EAE7F08B9A6338BEF7FE8B5D81583EA5C48 +375796372085876CADB21502E77F66764F67C11F69FF205DD706653ED40DAE7F +2E817457C6EFA10FCEC0ABFFF46ED0B112A515A1C5ECE4016683D24AE4234933 +03142D3F5408D6B4347DF87D6DB6D843164701408CD5388BFF0234CDE46DA53B +1060EC8FC73A31E10053A53CAEFC90C96DB930F7E2FBD5039387A15F4CC5C197 +BC2FCA011971EBC13844C370CBA676162715E6B66038B342F9EBC6E278965958 +2950EFFFBF10886CD3EE43741B66EE71976215F5C090D6FCDAFA0F09FCE2C56C +F7173B885FA1B6883057AFEAC9923BB22BA085E74426F4DD57E0E59A7E245A9E +DED2D1CECA852F57EF4037FF66D51ECD30FC6EBC95E0192ACE4A4926841D64AC +5384D1AAD0FA9DB932E199F0271DA68F9A3AB951B65EE7DC0711DDA07C92E153 +012EFC4CB575702DAE0C7CB6666A9F44DC4F965F6079F94FD34B6EA6E79B4EE6 +7751BEE8B721F16F8C28DF7EFE4A67751B642FD7E4460CD770A7112211513C67 +F934EEB3A95C5FA1D66A73B388DE69380A40D3566E883E89D0B292FD8AF4B063 +19900CBA3E1DADB33A64F1462156977764A7832E74241F9378F0BEEDC2454535 +54B334D4B71F4E13FE7FC588D8475812464AA709476E1E3807B385499C6BD992 +9689235FC42C207A3877F7D5982A87C47EED577CA1FD1ADB133094868DBF49B0 +E0FA7D2736793756CE915E2F8855D11807C51F2BFB36583525C6C74E15849493 +DB1B673D7CA0B9B5A42FD5635F509E8249141229087995C982AD8CEAA5CAFD2B +46FBEAE379FE49FB1B55BA76076DC69BEC64F2AA719FF103318B45F367A90D98 +A34B2519B8C82E8F51E4961A40BDB2ED188D231E94CBB9F8594C18D1D5A41A66 +C04BE3C0E42C23033775FAB6E617813B891963166390794D8C048F86422FED88 +67BDF4A60D6AA66DC0E8E6A8E2BDACFF68FD55ED78F74F36D055A479CE24E2C8 +BC2B57DC809FEE856ED1EB1078FE6D5CE4959E44305276AC319839C53D9ED91A +DEB117759DD3BD4F1D4E67DF5943DB41DDE35CCF7E6A4D3BE6CF3830B7117022 +3099E42EAB2C1FEBA35DEEC194C18B77437CBB61DF968C4AAFBB70C1019CCAF3 +79E1EC1F5708B8DBA167D4370DDEA7ADD3BBA6A0C1F8E20058CDDAC1CD380676 +0B7DB158FA947AA7F3A02B41EF46836E01FB741F91B420247BB9C8744608FC37 +0AF67329F7978F142DBF659B8A8F0D592046EFFB7F3124667DF9562AEAAD6E0C +A13ABFFC85BBC9806A2DB76B9311484D1D8A400C89C86DB8C678CD3BBA36463B +2F01F3B91D58D3078EE300BCB8D7318288BF602368FD70E95267C2879ABA5AEF +BAA8B067472FFEFE32CF213BB0BCEB53A9EEF07731C7FA6E399A59681A71EA5F +C3A5D118CE6D7107E8BF350DFA0A80B18C2BB265E74806ED288871925E4CAC07 +BB7465B0CAF4AC1FA6A4DC966480038E8B46024BBDC9D725CC03D2B93A4326F3 +4C020B091438DBCF6320897643DB1232CF6CA9BFF9CE7EFDA8491FA0ED29A77C +F3F65B317C4F1694B0FD10DD7BE362887BE4EEC67173752A2F0729E18BC64AF6 +01002D8979E937F336588281BA04688904CE31C370BB9E6117C4E640EFF6C71D +47C98933ED5CBBBE0C9B1FC7B5878A624756490220C82913D7FFFE788F5913F0 +513DF7AE4F71ECF422E02D643B4920E08FA3623A1B54AD852A402762E6845883 +3C3D12E45E287BBA870C4366A13BA3D21B0D25733322A4659459F4B2D7C0C5A3 +7E57B0CEAA8346399418A54BB6676FE800F66DC3438EE48B6F220849AB9F3577 +FBFB7469A40FD2E4BBB12254B27EDA9C05EF6D99D45FA79FDC5E14CEEA23FEE1 +C1CD4C26D9C4D00A8D7BF5E9830CA971CBD857C9B832225B1A5736406259D91C +D6D5CB1817EC7255FFB0CC7D83E2EE23ADB05F1CEC026D6B2350D806004DD810 +B92F80C827323F56E668ED87B0F442D59BEA68246DDE64610D5AA53B6C7FCE4E +F79A27ED30BA0BF128EB09AA2F74C2FB745CD3303B47727C093816C4B99AA55A +73804DBB5CCCA241923C0998A565031C185C63BC348FB7A77D51371F0598C0E2 +A24B2D4F0D4CE6F6A6EC0C14432DD6C88B4361ABB0D6E3BB813F6625B18D1666 +EB9A382D7EF05E692CA5CE9C94A8E90036D693CB11C54252718CA093A1C6646C +7B6956CF2BFA3C0568DBAADD9F604B2AED8F0F963764F8E0E327C5929434BB40 +A0319C748381E5211012925CFD7EE914469E0A00CD7CC1A6C6DA8D1C7B30D3D8 +8E6C8E3C8B248ACA15A1B462C3A6C8B2ED701F336D65D45B560F30CC580E957F +73F06F636EF85567A48295FDD23341ACDDB6CD86A5E8F1FF6AD6910E8E221A66 +CEEB2B614CC23178C033F6D135BBA8278244340E119E6C82A4AE60286FE02D60 +7295FB5048291C2A655A20FF265D5357E6F3DA06564A410A97832C7079164F3C +6D193F267729A247D7B96E647758F458D0F6F494F8FC284DD73F413E1225E9E1 +2F6A917D8099C41822F84416FE47D4313DE9DCA3BF3D2D5E85CE4CAC70E0C1DD +DA64EB3692C90C1608C8FEAA0263ED74ECF5F758BD3BB0E595709944CFE77145 +D5E5B03C9E15F022AC53DA6680CB14362CF7F35E914F6DA5E3C40CA98ED01EE2 +64F3709D9A4B7CC60B6651E094EE51A72A2E6EF80357E8899028BF4E25DF47CC +A92B51E8A3C517D558D2F4A369BBE8A33FDA6F3A9B51B57CBD161832E5F2B28B +A7B4F445BBCFCB658FF4ED9AA299D37394C80923DB7A315B022A22B5A341F858 +A25F772684BF0781E80CDF15393188797DF2E8608C9A48B849E27F5A58F80F04 +E90E1572652E92FED49E65DDE13C0D61E0D6B912DEDCA5B156B94B4C4A347148 +6CF516119A9FA728767201F1D0EAC329957FE795D5B9AF1E709FCEC0D578D9D0 +21D2F8F40A67F3E3529CC7D0440738FFF94C0FC1BC4209ED743885DBEA970325 +184BA629A5DECB34AA558730B77A5401124495094F127C9512B8DA883BBD23D3 +05C37C5B4C5CC8C762E8BCBFC9CC89F4AC1DF4861E96762E8F5BF196E58B544E +005BF4AB1A2E4F0226B8EE5F487AE6458B4312C63CE169AB0E32BF92FCC346AE +ACDEC572CA5BB2FF6A3A7D24DB0429BFED712FA4166581BD5B1D02FA35BEAEA2 +25083FCD9F3F238FECA1032CDA403097F05E6FBB905A26E8408B95742DBCC2CB +41A11E63166829B856767F91AD47289F2685734C6E95FD1513C121060C33CBFA +1DF5DBCF55199D7EB4D4DEF001830895AB27C74C2599A805E5CD9F93D0915166 +D4B46F68E2071025CF7D20E382995054D346EF5C3B1C308686DB495A356B1A85 +171A56C79C443757FD2E6505A4DF3C605A7E1D0CAA353F2D6D1035E5A1264F11 +8AC28DBDFCD0DE25AD0B0A5E925C8726A430A07AFE252D24D901C6178850440E +EBDE3E8A0F136B8A644FC16D5B02D2DE66E6486404C0402691643519A0E01F9B +55D2911E41E64DEDA8F1531A840E458C7BBFE061637128167712B922183B3D40 +5BA3E23873239A62E090BF06174683D2706967C84DB0E6AD95687C189B1F14B6 +8D093E1D89C131589B091E903AB2FE30961A638ADE54576C8B6BE3E80FD8C606 +3CDF0D132180627000FB587B4957FE8B65A91CD3D784036824E7FD60C16EFCB7 +114B26A392E24C58458EE510A6969A034CCB9178E82C46B067500AE85ED02305 +B00E94E4173EE1D733B7B60FE5B0223C21DB47E4FBAE6D590A0A789F004F974C +D1B95DD1FD7EE0B64ED316F8F3485D684EEE187B4E08B8F589DB88A8EC55F413 +9880BAB80CB43EF24C742F48148B4942C78E399940DC86D8BF84B88A5EC89E5F +BD9A2DDE0DD69B40FEFF423FDAE8226F7E18CC5E9F14F03DE0F486A4CCA21FC6 +6793081C69D63CEF16B92860F56F3966309F06B729FCBE1F86FDA8BDFE94962B +7062011520CF6929FCD531AB79606209BE467FD3274A1E87548D92E3F7862610 +9BD97EBB6B544F04E76E22B15B4E106690BAF9F37C243DC028451AE203DDA893 +D5F8A0C6AD763F8973B5063F0B3EB0CFA7663C6F308C256778A8E14A005050BB +BBA147B795C6D680CD425392B0A57988AE673EF0D997A204EA7136D26139FB7C +1C356AF9EEAED3980CB27231D9835571DEFC3498991FB2942638D86186AF73BC +FD55FEC65A66A35557BFD8114C10FD8F872EE976F0F231B40FB7320B92A0BFB1 +596391CD560BC7C28EAC9F342700671354A221326522B70DC5E832AE3F39685D +E6453C1110F0A7D0918E8E413BCAC5DD5A09524C059E5BD9C132586538F2EB52 +972B7D2C89D5A43B3D9697D23DD431F66768765B871CDB5FA608685C65B71A62 +1065B21A81192026F2BA728D35112C40704DD9E8332D8E374C986A6A48E4A30E +8C46AAA96718FF84A04A96949E7E6A653DD2556ACAA4E3B42E787EC539975B71 +309BF31D6ABA17C37CBCB4E4E0CB25F0BC09E2C307FBB375C1DF1D258544F5AE +2CF1819D249283EFE28203C1ADCF39CA6DE74F89AB5159680DF2992F6CD631F4 +A1185EBF7588211686B1DDF915270563B238D03CA0BA3C60676FF08259852BB7 +20B1D958E12BBCA69228FBA42E65969D02DB2A37F3C39B07CF455F473A449711 +7D7023F4D994E55DEFCF0406D8669EBBC92E3EE1050A2D24B1B5D4DA393AB9C3 +0ED709A039AB7E5F82099517E8B70417510BCB6AC6662A78D37C8733D8C4B27D +69E643F58935BA3043DDB9DE4D78CA38D7A965E6B797EAF65DF5E6E0E825AEFC +5DA53C3E50ECDAF26EDA4FE61FEB99E5900F61BD827C8F1C1CA156ABE502B2FA +548C30594DFA196183B2B27D04B4EEB2B63CA5F47C6263FECF253F8114496D21 +278A8DF5C172A66E60FDDF596254D729F67C4779420AB74A39D5E5ADEE663EB6 +E0D65ADBB179625BB93C569C166E53E831875219AD377F6EA835354C7F263F0E +A93C51E43F591BED9DA28122831BB5DCDE46D6B0BB91DB34BE123B75BC583DCA +3719935F02FFC65283B01DC6BE4D06280134E6C7E1EB87028071EC9AAC1B6CBD +4C8651ED2B26213533372B226198CDCCD42AE24CBB79E0FEC2DB57D40B4D4983 +20055205F06ACD3C1E345357EEA95492766B103EFD28E23A91850AAF157FD34A +9F25A59B8D807B37829CC139226F81A336E16124416CA69165A1D58000A582EF +DD388863B47EBFA763C31A82E0BDD6A0C9E2E7CDB418B5B21D607C6A2EC40299 +FA8E69DF37DF5EB775CDFD8AC0FB199C6E11739B644909CEAFE4D2123828DDD7 +FE23B3098C1B25394574D44FA5436574F34DD6963AA246E3B0C17108B4573B78 +8DC32286E9A466D15AC01E0470E60261C362F237096E8627CA4F87DC1AFD83AF +54C3CBB610E1B97A3CC046F83C1E99EE5BCAC6B90687A9FA6A402D6BB917567A +B4E347A7AFF8027E9A118F5B8905EDD930BA4A87E7115A3272ED8CEEE0195963 +6ACF972FFF29B2FECA6E38CF77B3BA25B9058BF64DCB2FB5122D7CEBB7201921 +617F419A92CBEBC15A8A4EF253F294E8CEAA76DA2149212E3519F233EE0FB983 +EC681C89E6403B5D852426C94FEC5E2CD93CFC8B15CB99243105F21415FE2273 +D0463CC70E5E1F45F559E3D544D6B81FBD5358CE5562AAEE8AB43A33FC4EDE84 +1E028C5B4F39771F9BF65141AD73990530E2A739CDD75DE47D38B55F66763604 +2D7B5A6630F46D2C6B8D3CF40FF01A6397D19BADBA8C4766D9BE10EA73A4EDDF +BE40B3572AC0533176CA444FCDE3BEC2F1907C63F6E92971A861AADB0191E6C4 +8ED6E10C231D438D6505D9393104204F5FD0DDD9058B7E04E5732C8FC17814A1 +10A1463B5EE58F33672B5F97CCD7BC6936AE5A49719BD68B1CEDFD8E5592C122 +3749B86FD0E373AECC1188A639723D4CEB42B142062534AB42E766BC3B709986 +57E70E68B9740AC5F284F04BAB28239B5DC8AF12BD5E39A31C9A2E1C9A519D5A +60A966DF2A68BE4A5EDF5392AB2CC26D3D3274119B1FFE40795C9D097541BD8E +BB1B65E7A2B94AA25AE5C57031959F0861F5DE27C61C371704B3855DA678468F +2A9337DCFEBD02EFAF984D01B5369177B0301646C57625ED4C455A4219CC042F +C6BE63A086360AE4A9DD5B37949F4176E5F5601DBE7533BC590CFEED94B31EAB +A68B6741B5E32C610F6345620B94E87F14B79B1D15F8F3A638C94E9A9B7AE4AC +FD1A5FBCEFCA8015ABD25EE55312DF3FC193F68515619DBBABDC301E09399425 +9F15C1D4FEADF2912C676267DB8D5D7594719A5DAC965C08812FE51C4905E2EB +0CA991DF28FFE9D5BEAD055656608714092626632613CD297E11B629ED77AD75 +BDB8892C98DA992489FB138543CEE8D294B2AC6F924E2A622C40059A180665A6 +698EA5BC74994374B85FE9D541DD4C9A7782F66F0D5FB928555616CF6B9523B4 +4780DC444B4D3CD2B9C2B2F255F8B2C926093F9F80BECEA3DF2301DA26B87FEF +CEFD179713B1EA0C8CE779CE59191D468613F0D708A14225B26DD97A64AEF55A +AA6134FD3473888724BB3F34D2171BF6F2E3DB28EE4945BADB0B5B5A4D83D087 +920EEC92A5B85F1DAB6176F44A8A36A503685A83928836E7FC4079F929C29269 +F7ED0F93B67E1EA9D0C3055F16305152DAA2E79E08A89D6A29D686836A43F5BC +6283FB2C37ECE9B467B6DF24E68062D1DCB25ECA8AC9C4BC3D846F3F95D91712 +B90B7727D06B9143C4F215B04C126CCE6F38A8512F39B14A94BA956EB696549E +5A795B86BC82C8BEC872D9F3D0B4909DCCA395F3065D7AB72B5DFF4AFD6B1B6D +8E75CE3316230349FC4F3E889A81F2452534AA3AF82C5768C77C1229975197DD +B8D26C9B94921A80A399BB6B292EA56D7E2217E8E6E8FDD817E8A2DCB986D1D0 +4F3BA37C60C6CD745A1F33F7507818676EB53F2A7E4B0F97A30013820BF6DF15 +31DF184711F646B7B9CAF27B396B8C218036A7B668F15EBB0808D9E8DA1B7871 +3FD447EA00E5629CF2A6DE3F411AFFD4296B36F8DA06D040FA763E0AF241ED62 +80468F92A98E9FA82EB534897362208DC3FC4B268BF646EF99518430FC3D13F0 +9F0501EB8540FF16596A894A6C7DA4119D473647E4E2CC534EDCA764138ACE8D +426D6FEDFA065F9235A8DD34019FE0922B06DD75F967C8331ADDF79C1D7B1A11 +B68A43DF4797C9A81C1D3EB9EEEAE7D8A9EEA3C08C13F48C33FEF4C5493C4270 +5EEA2BAEEE9CC40D07F1883BD193B11EAF9E0CAA3214B3C34BBB3C27FAFFD949 +1BB4CAE77B627E300325CE0141854BDAF24E73CF535C952997168E5DF594C269 +DCC646A460CE417967E3C09A63E9125E01EE2770DFF73A2694D94549EA71799D +C086B5FF88292D1B6E7F3FB425809E6B0BC2671CF26397BF3DCC756DBB1920FE +470B6D9239E3BD4DECB5EBEA0D1289734E80D8D4544DE8957E66306E4B638557 +212699F0E892892570AC8C060EB37A64B471DB2CBF05CEF4418F787A7D96F04A +8B55B4234948AAAC51F8B34792AAD1A75956A4642ECED3731E34742BDB338CCB +0ABBA52FE5901663ACE4E026CEFFCAA5EF6BD97A4316877C7A976E5523BA4A9D +82F6717666FA6F765F51E414148A4666C293B24F6283FB94E63F9CE245CFFF5A +3C6B620EAD4BBF2C45C1CFCBCD758DF350D0CC4C972C72CDF4A19465BFBA4E60 +ABE57C22DDC94E22A4A396A3A99362FF311AB63EA2E790E0BED6F62AF8CAD265 +DD6923A736C427086275A4E2DBFF09AFF176D01D43F5229F311E0DAE01E57F54 +A8406CB7843847FF1901EE9B0F6B915B4D6A4DFF13F469AFABF2BAAC8F54AF0C +01F66A4169950F247441B5DBCB35D23A063FE9907FF9653BFBBAC43680C35791 +D2FB66355B28C577D8D553071664685A1763DC2C18074A5FC1FFFE2BB4E36525 +067A907027F1EA6303D866DD5DB69C4457C01FA0A1859C1C80133BAA88D7DA6B +E04146BB1C3FAFDB2B9E60F582BDE0E73AA446F9008C97BCCE66D53130A26727 +4C52271A6CCCAF062E550A4318C940BDCD0F17FC4FB5F0FE8BE15311199852C7 +20 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 @@ -1672,209 +1669,212 @@ 16B955D4A1EB29BAD152EC888572C3D4E2F02309DC60E94272D2F2EBCFE32969 5180EDCE322BDD38E3B34D24819E03ED61C913A9FAFE2DA1822A660C246B1132 D2C18F76CC413D4AD1BB8F7A6719FDC7C7E54307495BC0E671CC6F4257C82574 -5FFC9C7EACE612207FC80AD04F0CE33A9308DD615A4307677F9ADF6B98D66A77 -2510BB8B5C985DA4658F7637BB4C7643AC9CC424E2571EE4CF5C15C7EDD306DA -C41DED0B1339553A5F8265DBD9DA06374B37D77A9C9E4AEBCB4ACA8B909E9C48 -70C16A5A042CBC8825CF675BF574B16254541B69E203D5E3CE29C339C907D11B -28F9AD8DF700C945FF11B0C99172FE6B25D131526C31E19D5637FF4249440651 -86C1D4C8A7B60CCA184FAA3E27F7244698A99CCF94E9135769C726307F940449 -48239486ED7BA4B8DCAF87EB1D2A8D1753E7EFA9468924DC0BEEA33484830DF0 -2CC726EB379B5668550B61B2D401C5D1012B16B9E2BF0A336073544F65124481 -F23611E8675B40FB28F393A1A8DFFDC13AD08A67AF396D454E3CCE141925D9A7 -9CCCA2D829E4DB2467F2F8CA1BE3FDC5E13120BFCDD7F0DDCA66E65FA69CC475 -866C8A62DBD00D09D867D0040BD804A1D7F17F3B8AAAB21FD48B11BD96C13774 -0BCB85CBA1E12A459B221ABEA106D74BC0EAED03ACBC0120CD47294D9D0F3B96 -CB570779E46519DA8854697AB48089B56025D3787243666855333F0AF2625DAC -502DEDFD5529924E50B1740A93E8B58C54DE09BEDA69B4FDA8A37AA6E32F1ED9 -B323763F9DA9A59BD9F179A567BAD612B8634FB8463FFB073184294038307E22 -BD0D05B160331B848E7D7243DC7EFAF26F8E6518855F679372B94938E90E7D40 -9A45E12A3203ED0047D4E2CBAF8D5AF2191EAE42CCF2E2939022FAA57FA90CEE -1FAE7BE6E23C4E32D372908E149B2096D480B82C143A26C604AF950FFACF596E -3CBD6C5C86EDE699622F50FF70D278E11741D18CBC6EC804F7803FA00BB693CE -2CBA9437C5041EE62CDDA5B5E4DA501C6841614AB271633E748AEEF52AB40E2E -245080043BF749542EDA7FF6B74C41FA8B61640E4DBA1C44226785F2E3DDC7D3 -B6B33B44E511C0152B679FADE241F0857C3CFDA8FF5E0FA4A7BA26A1A428387E -1CE83E956CD8AC28EE4F4A818B2F64C72FC65D4D5054781B6177E54C75AE1396 -505E5562B7F6CABC9515CAC5670A69AB00668ED859DFDB673378080BB5539A18 -8D347ED0D06DF019859CED07566B5B51376C5AF5876D3232DE8DADE7909B13CC -8086DAA5B7AC78759D0998A0AC451CB7B9491A681A58D4FC3CD45555B20EB170 -31466D6B09ED870E735606D2E91201F85809A24027035B2BC5761B71FDF655B2 -63FA45D0633E9A8D6890B6C4CE4A5E237CB48B72A2A2BD8D2176408BD8F6B2E5 -A39668D92EF921178190DB989A5C6E3FE318A56D799CC42B6B58DCF3FE6E8ABC -7662CAC717B368F886D44F0ACACCC4AB8E8C24D35869D9BAA91C64917796D2CF -DEB05E44A43074F1A53ABDE558457687B2D9FFF1AD7A33E64625B35E994FC613 -5F66CE83ECFE45777AFDF7C9DE3284C06670B8BE2C7CA2DC73244378FA73CDFB -02C7DA8AE1E57FD5FB6F41707D4D90C2A4E3D0E77D78867976FC53589FE4D0B7 -DD6AC71C010C15B3A8FEC1E5673EA53D928D9A90040FF6E3C30BABAC5CF8BBAC -5BBF3814E9709FF2C8B59C7C732B0C7BA597E00E61232B4B433A74646203F260 -CF694D67E878159FB571D766C398AC5755082BBA1B2A5E71546FCC94999E4262 -F18BE1A41E919FA7A53013621A6399A39C74181FEE13D4003468C7A343BDD085 -FFCF2E1EFEC20119FD923E97CE26A66780BD8BF09D66DAD588ED91DC369B0863 -C22BB347374EF5FD616A70CA07C91E5F48849D09F4823C8A02A6D80E4DA5DCEB -33D190D72702A78FBF7328A7D5ECC822D907B7908CA44BAB4A959F21ACD2A1C4 -6C6069DEE6B2F208628DF65FC40A05ECD8956505D43F883E7992A2B7621551FD -34C580D14136445DB52C9843BBF00F92537A65704B0DD575B1BA7863F971F2EE -479A9657AAE6627A321309A4A12DEAFA0C0B2EF5EE8C0F75ECACDD58E610938A -5907433061E78FC48581B87AFDA9226ED79555ADF9F0443D60996A1084B0B4B4 -C9E01EC092279E300CED0D34EDFD946C5660ED85CC0512F8A8982A7DF771E24A -D57B07A67D2745521178BE4C259EB3DEE7D6F820C40A2D939A4A484559207C1E -0719083EACBA076020776AF7C45DA52CB7173B54237942CC063E5491B8527185 -15E7B30ECAAA49124B9915D9AFEDDB98513CC30EFC161C9D1F2371D8E0BAAAD7 -44AD4BA2CE425A0B8ADDE7A5056645F9FF0F305E43E8CCB0869E03F0F510FC75 -EDA9CA416F5E14E6FF577CEA44706C2BDBCE79E7C692DDB097BD6A852A33925C -8A30E83FC93CA7FF3D60062F06DCBDC9AB390622768B7F2370D4FBCAD40CFC1F -061899B30F760D58E9787EA232AF7305F2E178BB101FE1C172D5011378B93437 -D19B7F3505A8A758C9B0C2E395EB48F13A5DE5B81C085344E3E57EE6FDC6BF35 -6CE8B2B48A59AAA519D2014818724948FDE669EFA9DD4BFA76319E84B6928C00 -CCCF36793E1A533E3E9822684C4F0B1A60297EAF24D79FD1B728145C2F2EB2D7 -7F0CEA0F72B6ADE7E8AB02501EF56772DA610E1A6D855AE4BC828BFB3F36E5DF -E1087B9732BADC3DCF7B72C1FA15A1517DE3DB6360630E55952A0DE142EC11C7 -0DA0B033C405457DE4F619647B623EDEDA588A29D9D457C835320A1FE2E879AA -18E5125E95D48EA5E1886C7C8B353CC3B5C3C91333E48EE9E6866E23107C24D7 -738BA7F34A9B9AE25C3DF1DDB072AF68202EE17413929E4B39C0F165441BA9CE -7587D7C6F181EDC1F55C51B7D8D04FFC47CB79038680FA609360A9BDD44F3787 -14CFBDB4F730BECB4876871DCF0811991151113C3C8F27BE0651F0B97FA21B6F -CCD040F39A945AA4549C0327A380F6F2D498CD074168EE3180DC205D18EEA359 -C24E06EEAA49F08474F7E441F4A2C7B11C6BE15FF0777661064B66A33DD45EAC -63B97B312E4B93C10F8E583D3827E6CB814EF8B73A6AABF11D638C707750A765 -92D5BF3C59B961569D9BC007DA19AC308EB09045F79D29BD970C4943E4ECBD7C -0C9148378BFC202102B297A6511E956BDDAF5A64B84BCC16BB6C4C747BA8D422 -508DF34DBB3F36B9EC0188EBE1A1288C1E3AA548B0D799D73DBD6584FC4F795E -1A4B0DE9D930B4ABFC9CB303CC0380C8664F21595EB9EA9983B21A4F3FB46D1B -E5A16D5C58C12323CBE9CA9AB79DF7A2776E1993CF3AB4A6177BCCF147117DEA -5304FEEC5903A4982A77793C4B360453F865540F5B0EADD4FDD40F85C72712C5 -07A6F447BE494A85494BA59B241540E84510B3BDF3B6927E69B006567C04BA6F -AC056E315F53971769687A314C874D8E62A383394A8C1359C9254432CE771A3A -61655E881B22D7FA0BCBE24C46EAC022992FD5904555D84612A168BDED0B365C -EE54FD4CDB9DBD9AFBC3EB392400446D3A125D3C375EDAB7D551876345FF6343 -1D31E6A4E82AC340B16B1266D9E90418E8F3796F1A43DDB762F03F828981CA31 -2DFB4BE9ACCEB2FBAA4882520B01D36B1A7A98602E9D3951B23D3E5634EFB973 -485C863847E780463B29F61C4FAA11250331A5C0D4A2E03A1FDA25D8FB40E464 -5384691A0CF3B929561C6F3E225DFE52C651B541B719FD7D60F1D23C8405741A -70FA5024A86039E1B2BC64DC37AD27464ADA20B980ADF292B0F53BC7E5E2F9D3 -C40C4D5FF6EB094A1CA0159EC547F0A19020E580A94A4833F4CA7B94190D5DB2 -20530215E33B34AC25C7BB38158C9369EA2EEA2EAB6A29499DEABDAFE5243255 -CDE450920F62BCD0C8B6455C3EF9BB44D987A2754B8D5253D1E02DBBF3A740D9 -A502CDADF38BDC4ED9CBF33E966CA6D81CD9DDE1DBA86A768EA720868AE9FEFA -3586048721720633D9B73F16A5E0BA13644A44D64C8C7F2E7B22E488D77B9177 -F27E7A960A65DB9674C9471175F136E436E908D10DE577F8E318769DE0934EB5 -15C9AC907F2799A2123A745D3813FD5CFBC260A454797E8EDAABC2A727B23DE8 -96026CE2CD0FD891197D1751AD87F1DD61F2B5406B3390E67AA7A942FE0F746D -0444E21D51A6A103FECFE2FD2863EB1BF9FB55BC75EDE6D3192FCEB8267C656D -7186ADE66BA749E1AE37BCF784A1E467D0B83C73ABE2550510AA57007771DE91 -04485B4601D14ACBD97C4BE879FDDF748AF1429ACBF3D41FD918A4D238D26F95 -9F86669789C9D03A04FAB2308419482DAAA77C47EE164B276257F0114D370F41 -82D109A24A95107695F87C6459A7EA5A28A83CA6F45029E32DE497E76DA7F99B -2A87C4936275DE2DFD7DA865B8FF52668493ACCBA80AD419443D1B2C0659EA69 -D16680F63A27DB05409EAA1E94613A6100E0CC78F8EA507144C9BB13E29CB482 -5A813BDA35C973616778E273A01943FD5FDDDF7489FA4D49C50396B07A06C86C -F2CDA26CEDB033B50E06F817A4F0631E0659E49726DC4A88F6A4D3A355F9966F -AAF445EA2B16C547B1EFF050879B3EABAF2B868613E9B47AF1AE7E90847123A9 -F4E09E7D25D6778A87011AF3E42B8F05AAA2989AE67FD8DB9A560D4C75E79196 -602996F939A0121A321DD323706068FE1CB46B0E95DC45845F14C06D9437EE31 -2BCE925B8742D0A1A226F225D7EC6A7A807DC1977C9195D91771BF8A5B2BE31A -15D4D206107421213AD41CA456E3025F069432F21C4AB291D9A548C65A49EC2F -7A1C5A640FF17D8BC4C04487D0CAD2E08DF0F0524B67CE49379A1E81DA971A8C -CC237FBBA08A90BD4A882DA93F915C7F3248569BA03794B9C2F12D51691B4CFB -CA5AA67E71599B33585E21593CA83ECB9CFDD5C547DD87694206B0AE32372B06 -8825223E060F1BECE3FCF5E76B5C0F963B7637EF59EB389F12B5B0CC5DD91286 -0673258290FDD422C4450B4A9329D0017FC2105E09DC969232489507B76CF9F7 -E18550397EAF067B3A9E0347970994A6507C177EDB973A69EF7C382A941E69DD -BFDB14F5B3299BDFAE7CCC331CFB83FCCEEA55026AAF4757121A2F577F2EF618 -ED54EF62FADDB76D4FBCE11FBDDB7F4FD6B919E046B5A0346A0539C598CD9A22 -BD414EA34E25FAB77D3769E05EEB5A0FD51EA9C7A2433DB5AE9955127C403910 -2B6A66262BC8B0657A3973F1482138AF77E9F8774C2658F15645660C90973B23 -9C30EA7DA830BA0C55671AEDFAF0FD96AD60098E768EAD067F0A63E06B0CEA3B -B7E6B4F2D00F575DB0A6B078962B4CB9709A343EA520E57E826C9E89375D7F4C -1231463A236751F69E097A994E4043DBA8692D7E9B16E214575D0F2978518E66 -397FCA66BEFE1F4A7A1B7CB123DD85A90E1A0E88185EED105D7995D0EBB936A5 -76CDD7B4791AE48A7368912404F3A34A2AD049E694CE9B3F3C648143C7C2D6C6 -E78B173E08B7129A1C443B6D4A307341184919EC3FACAA11B3DE39B10E855749 -99FF4ABB58030091CE8F975FF327D2A824B95437D993702700EDD7850A7A01EE -3DDC985BE66619EEADDCD13B328CA490DE02087FDC35C1290C2F5D58E1ECE85D -2BF79955108608606229028ADDC9EB448CCC54D7381C7EA8F9590E1BE3551FD8 -8D8BEF116597CD277E1A6DA692F84C83513E4E671D6F48EE46A78B7BD2056948 -CFA4DD257747BFD38E6813A3D83FAF54FE128ADCCAE38D74CD0486ACFA15A6B0 -1D8469984101347A4F34DE18417F089C197DAE1E9E3CD5D8D8FF7A09DB77BD00 -986359424222FFA593449F7CE00221DAD4731B341B11066FD3DB5138D163EC82 -9D89F5CEA8EBD5B9BC2FF6A7577E696A3787B6A07A8562648EBF9C1435B0272D -995814A9B100631205ED935D0A50866E74A8E332E31654A57C031541B0DA849D -9B8221773B03527FC9B32F327842CC6285BDC49350501D8F7B728CCA5AE742CF -010F8A859E411DEA98F1ACEEB0F27890157F804AC9CD2B3DF5BBD1EA4C72BB26 -0133A4E0B21D07277D7792E076D7F11EBE47E673972DF8A2AB1DC562B0CBD324 -712A40198D448E0E5AC50F6AF123DDA23DF6AD4587030AE9AB358A64E3D175F7 -D278603073AA2DCB65626788B2919F675A5D41432DB8DC56B946D2EAD7D29B7F -A564E0CA7E8D37EE506C87D574B56E32503734D1A8B90BB97E47CB057FE58799 -603EC3F828B7A5AC3863CC169C0D8B40C204716528F4FF3BB206DA9CF7A0C325 -176939038B142297A349CB7BFD48022CD351FB7C99D2827A5F51F4772C437B6D -8BC7DFFF5A46DCAC13BBF46CF14A5D8F1E9CE23FF35614F408BFC9DE7F36EE5F -4947F4F664D5CF47E53377A4F9179C83D62EB8BD87F133BF2E4DA3E4443D8BE1 -2F206585D371003CEFC9BADC4547C28D21773D2853459EA4E7790743E1D0A144 -56C80938A89879D0724B79C8F883896099B9399BA2D7696225332A1EAF8C1365 -D582481D1F93A28459D60DA6220F602CF121CE16F62C22B4F98F379CA401ABB6 -1843F2A4E7096D3982CCB6DB6DDB9ABE784EE9B2762D3A8E5768558755C63698 -7F02DECF75D2FCC99CD93494E8C5021D3B48F10E153020A5E1EB547311E3265F -109263954E7DB3409462351B6311ACF63053ED32904B98701A6B99F59915E9B6 -2AD813EDA9523A4BF3E430D8793D10E830E6E620892CCBA72BF9D437EBBDAC7B -B237AC58DDF7A684F5A338713C78396FFD6B92816647444BE9BCDD8CA0BB2E56 -4531639B3D74D2C2B369A79AE166109F5FE26A55AC2E4F7FB25A0D4FABD0FE99 -621A447278BE95EE1D72D60B5B5572CD302B01989DBA8056CF701E4C59FAE8A8 -D8853CD5E21952882001BC6CEDD8E195DE5EFEAD54C7CD2B4D1E0AE4893BFED3 -6F5A4E156D3B4415EB827F7515405C825CA42C75B9E9761FD797078A81997863 -99D1A40F45A65BEADEFF5B1818C8DF726B7129E984C33516CE9DC16547C158CD -9DBDA49082C9693C10A08C3B623ED921EA5F4BF064CA812607AD44B779C9ADBF -5C7EA8BD6F0DBA23B2F8505EE65D2DC384ACFF2D1ACEA8E6C6B6F18149D48D19 -96B365FA505B474B7C9292701736A0D48EDFA11152F622178EB33156291EB6B9 -BA958F5ECB78F96BCEA8D7DAC90803001513FF64E4251C48FA3F4AECB8CECA8F -A3247EE067044CF459EE80D7DAD8F02BD6608C27A6FD5BB9880514A7B1FDB33A -9AB70A3700CC5DE44973D1103EAAC669DE3B41E53F9D6F40F65580FC1365E0A9 -6303A8545B34A00A20AFC15851942FE866CC3F1FCEBB71C9673B5B5A086108A8 -FFE0B0B51DB22813E11BBBC2EA53383DCF2D7B719680795E05541B026B41B6C9 -CDE5B88522A362C908D0E65A1FE1073068507C63AB8FF157832AEE7228BDCF26 -7207EFB3A82CED3A2411064B24C50A24579A2A66A6FC70B7AE48E544B790D375 -7317DA0432E4893F70087D68F8B382FAF770C3B0AE74119A7474265BD6356FEF -CF9AB053E9F2F53E49E800969C7D6F128C69DBFABE01D464494CA06C24E0DDD6 -93FC8E0C026D68DFD3FF29A6F6D5D40928E1DE1351D457A6750F1A75DDBB0B13 -343B3EA6791AC35A8D72E685073B01C0DDBCA8E07D8ED48EBA8E6EA2CB380118 -6D65D5C3D1C081058FC9CC54E9F49EA02A8FAB4CC126CF85E51960C402CD7A55 -E8FFE2F22EDB8D6458F97E48A901CDB89BBCA78AC0DC93C1AF4D4A91D730FDA0 -577B7F5E5540528E36DC29A5EA4E99C3D8A3D95B2E9926CFE3B29FEF6D55333E -B87C4B28FFA9A582203ACC9528DACF226E78041B2E675AFCB823ED7B01619F5C -7E5EE4F4B800040F96F2693CB79F41A375D8C502E1253D74210ACC226BDE60CA -F7431720D00720D3C900098D13D9775A4E94A91801C5D460DFF396319F49AC57 -D9318CD4DA5B30FE4A2AF67CFC34961EEA35B985D02F41B4AF51679CF1131327 -78C0A045D5D259494F86B486767B0835259C9976314CDB29F0E70DA314611903 -BB43B448C7E0FDDCE42BD623D2919B0EB1B0D5C92C0C6D44FF220B12612A6E9D -087D4EC32DC0164C3C1EEBB4D42C24403DDFA87BD9397B34F4129BBC1F5DCED2 -EC698ABBBCD76137BA92DC8FF989299B5AE9B0C9FE7A7C4C6AB9A98BB4D9F86B -EBB1A5ECCBA6633459814589DB7BEE88CEC1C1C4BE0792027C736C74AE0ABBA9 -B7AB5AD51FAEADA4A53684D2BC12E6F60C3C19899D6DA7A0691CAE19306FEE5E -C3E3AF07D6D6D1921DC57C02DF25F3CEFFC56AA2A284FA26C99C467A603F410C -38642DDBDA66623FD2FCF0A3BF49252E1F3B1EDCA0C39D6466998A06ED2D59D6 -33984620E4C5190365AC6A15852E9F114B7C6BE44631184E620CFC547B061DC1 -B0F28EA6198560D45E951FE8CC2F375B3F29954C14E7DC2F1804218C28AFF3A8 -B01643302DA4D47DD87E5C54BC270A012E3109526E5E78406DAEF9D91F410B7B -06400A2A08E2096A391AA15D3863A7D276AC17FD6936833A707395DADB969E29 -ADD9E78E54BDD88E66292953ED2783010B32CCF920349E866428533680CCE907 -F6F0E92F2747FB8A090F33B2ABE187D25DFE64B65B333CC84D730A58DD47BD30 -D55755AF60625D867503C5E5E5AE2B2526E7CFC602754DD6AC4CB2BA2B81F160 -10147BE356D1F8DCAF71FBBCE217456605FC236B8CD696B617E4091889DD5481 -FD861F9571C92DF7B4BDBA694A36B23FECCBBB8D44E51FBF37ACED02CA5C9409 -2E8ED9A632E1DC490D7166A23F71572EE8670C8A718DFC74ACA4A28409EE1A67 -FE3CEFA903307D670CE1C938D2958E26ED0497F4BFBA845EF1EC62A3C97AFAC9 -D37A9785B4F9C6CA19BD85D5166C4035FB1806A7480451D6AEAFA0D64803792C -E0B184FAC3BF110C337218585C4EA31D4E76E292328A93194BA54AE22515FCF4 -EFCCD3A6BB35164AE4DAFFF7CCC786D9E90BFA2478566F41A5ECCD277DA32B7A -10ED094F6E7F054393986B8B7E1A08179F6FA3935BEA925CC8C7EB0661105B64 -07F9A35DD203B9D5688A1DBE7E4F52A57F439EB54401D191F0AF6F9B73E45FC7 -0409361F3A7608C499DE7BDDDF831D4FC1C7442E1E713AB71A4D38210B3612B6 -15F9AB3921999286C3CE9271F36D738EF691E06468B06E3FFD19CA3181CF5693 -A0E7C2CCE9B01724AB154D6510343784B3EF0DA3316E65CB37EEE337BA295447 -7ADFA6BE5D314DB0F596999279BD833E280FF84A94EFA52030033023A42F932E -CA1F9A2177C83A6E9F7ED2FB89D4AAE5BE8F2C4175FFA039B8DD7FD9604DA38F -8F1A2D98B7143D09A27CB1AE73E58DC9FF4CE1971E6ACB3FE713D3DFA13E7C53 -B2454417A5DAFDAFB094C0811D9A12AD6B212A4FA2DE5A09E4FEC5D99BEC5222 -F8BE9EB2B7 +5FFC9C7EACE612207FC80AD04F0CE33A9308DAF6F02EA444F581D7EC9637BA31 +D088D619ED30DD76E1A2D4F2450E4E7470C9ACF7E73441A9C1F627CDA0F32DE0 +B7FE8F7DD39AE7D4C671D775FA71CAC0E3537BEC8956C46DD81C4B29B4C65873 +DC053BC3827D0947EBB8CC1DF80DAB12135E54AF6C489598B58A687011F2019B +3A6ED5AA1797B6F58F3BE160573274624A55B69129AC4C86B33404FDE406D5F9 +76D0E54A25FE781008B57DB7C863AE75212D25AE5B959DA89CB28A299656B276 +36D7113C9E7417E647E1FBBB332C0B838B6C082598D7C606E50D7E2419EC543D +73E361E9683B599A2C1050C5B73BF815A467CD414AD37F41BA211B4BECC383CE +F8FC5696278F0AE855A1101E512572FD3F30D60BAE1A0165A568B53BFF23CFA0 +1CB2B26C973E5A2E0B5FC41C5A617CE7773DDF19EB06A6472357F18F5FB5B813 +9F7D3975EE660040E0A6005FBF0EDAC846F282D26F0017681F4BFB857C85AE34 +484871CF8D84C81D069D8A1E39F4D593987A2310D39647AC136EBD7A3E3F33DC +5D56C33299287F3C7D0185C63C3A461DFF50DDDF11B60C4F5295EAFFBDAC7509 +876C1FF578FF9C735AAD06B20557CE5145E26D92B5D243066B90929ECE3699A2 +42D917A060AA52156666C2EEBC8DAE499A76517D1B446B248A6FC4CEDC702AB8 +1E7EB23B316194FEE46978631540C3E03F894A7B1F455AEF9B68F03B60F65C53 +1D145E11BA5A69005CA707CD5A40A6139F79E9CE2358861325CB6F8A415A581E +17894B6015061EF692007635A2A07B45C5643B472F5D643E9370CA65A9600375 +BD48A9F386D97E7EF73E5ACDF01C002D6EE4DBC308C6DF6A1C245AB275E82710 +5ED190872415C399EC6EAEDFC8112DEAF3A676CF5EA79EF0ECC1D0A282FD25B0 +483A086E80D6FA1FE0667F9966B4F5210F4795109BB464B9D9E65A4CFAD7C76A +65C58E1E17410AD287C718BB31F45CF07DA667FE54D204BB249CA405CE1911BC +DB78A66EAAE856F78B9E845F4A2308F26A3FD357754C7FF2CB3E67620AAC7A94 +D68FDBBB4CC2EDF8A16C1CEA9CFEAB6F365697A2DB8C81EB1AB24AA61B2B9E11 +1F14AF667211FE2EA12A3752961D4703837DBAD5FD3B166360E3030E4551B229 +9877545DEE34797938D735C433F6D1A5DBFE270697080CD2A37A0CD58FDC2709 +2D0C0DE31EB495BA7BEFA3EAC8684AAA7335548B76BBDB4DD582363EFCF31683 +6000D53A40FD1A58DDEF046F0FB6EAB9CC1ABB4EF43BE3290BC5FF3CA697058C +467D8152088D39D43FE419B827E3C871CDDFA5D45D187D06CA3AAA955FFA82B6 +493A56CA4C09B8BD8B81B2708CEF273DC837B3FBCE3C4F65108C3485EB3B1A45 +FD8C8B349DE0E7850A34D6310E51DAF1770D851EB10718FD76224ECBC0743903 +6AC4FC0B2C9129FA25BDA33FC2A4CA79DDF407D6779292C62461E803C999A03B +02FC759C1AC63A85BE4E9777CAB832739FCC2D90E042B0D45417DD1E60A0EE16 +DDEEBCA50554BBE14B80B55FAECAFCBD1D06EF02673AC032D935B86D67EF2182 +FC9EF29733413073B7C8D12B2D8D2946F86B59F4B959AA5B0E67C3466BB68C83 +DF22FFC1A1401E53406F11D1A37871991E653AF8963B7811268DBC09A81C2CBF +F923C5B77FB4154A2B639FE3A2C0ACAF8CE91DA065AF06B5B038199CF7AFDB0C +849F57D9BD583A842EA47DF51A4E55636149C9FC96042B25C1D58862C9A7BAF3 +14E7E9CA614300125C7402CF26EF183AC60B5492C5B0434EA03EA166CC830A26 +341D91F19CE201A56F6C31FBD0099875C164824B4E6A20218CE74E70B924D73F +2597FC32271966F0B0CC099C4D80D291113AF321CC73ED180DB48ECEA10F975D +B6519F1FAA8B24A0851C2BAA1725E3EE1BDAEB900F354179EACFD9DFC4D84C9A +7CC3C400B42725AA7EA24E69C48A4E909E1170A484E8D836EE18B44F765181F1 +240815E42C4FC2ADC7811DC3B4B22450A410DF068FB76354E89518A4C22DFA78 +87CAE6D8FE0AA3C77AE9AEB76FEF037622B7530539FEC470BE8E76087772E35E +F5433A47B031CF604B95085B6DADFAC82391246703B7A34C9A14A296B29D5635 +FDDC90C029E76A042F505114CEDE5172F4261FFF4A4BE84A7A20CC9A9995D292 +0DB8BC24A9E50C0CDF1871074F86FFC52216583DB2BB7812A768C04B7C0C02C4 +4ECED1325EDE241AA7202EE8B39060CB39A29F71444A8296C71BCE0327D4E439 +A3752B13C5C32E88D3E298137A0C7503FC5570FBF79195A7B656485640209E48 +688663702F80021E9BDF9769EB5FB4A3935C5AEFA1F326DFFDD8C8B3FE77F74F +7DD1CB7EA7C30BD10464F5E63333863AA12D70C1CAE49A0741B3A0FF1BBF665D +49A38693258FC9A722DF2EA1E220E66F8225D462AEA02855F32C598BF160643E +38D7AAA68789A9931F015ADACB819F18FF061C136E8BFD9FE028508AE8871566 +646CB448BC49FC14D2B84FD3781870D2F3C78901A8352C67BF2DC8292CB90013 +F9B1BA4458A4A20F119D4BEC340846CA83A57685278E8F864F561C3EDB1D4CF7 +A4E5EA475721E33350EF7C979AF260A0BD6B790A0869D138EB8A730F2D5701B7 +7AD4E3CC0D90FEFDA2296FB036CA35F9BF11DA136DA4FC094B7E2F767B7841FF +7A7C7DDDDC20C43B293EDB47A6F5C6210200B05753B7EF7A6B9F830283A7D7BA +2A86036CFECE1B8DF87A60A920DD49FF9C6D2A74469DE8416FE86B1762DB624F +FB1606998C2301214F13125C3F5FDE94D53BB20ECE1AA75D70CC7BB7A315B704 +4CC3557F9AFC782BF947292D29076A8AE7C52D8F01372FD207CF90870EAECBEC +D9B48039B2D3DA67DC479AEAB7B67D11D4A2712F7A9C3CC81911564F43EF3AD6 +6783FF1DEB9F369208C7DC7C49EDBF9CE337DE885D70F07DEE03239562446635 +4603F240D27BA90774A102D009F77DF7FCA23B447038FDE325DCBE35CDEF04F9 +56075BA6537DABAE012A088709F0186630BB2C756F9AD4826836D4620D1E475E +F441E5EB7C04DEAB39B06ABC33954A261AB1E9282EDCBBA9F62AA5A7096569D8 +3A6A782CD1F7D854D9F98178A5AB443F09EC7A0A8CDE31A9D1F1E1CD92AB3D42 +7E5E2C137397E8E47D182A9462105D10D7F20B57FAB1EBF65B63AA09030C5090 +DDF53E4371462EA3607831D51364DDBF29E9D8B66D0EF27C4F858100D3746039 +A47DB60BD35200049B80782CFD3E156DADA50ABD445B315F26DFFBDCE640A0E6 +EAB0B79BF78D8F32B9BC288FCEC94AD49FE622D24B9C8A7F1921179976C5E449 +601D34C7160B9D9D342E78D0DA3C00ACB48BC78267E2A7D6CDAB86E06EAC9E99 +E97D129DD5798A617E3CDEE079ECDD29D2BBD4548AFBB4F6BD5F580EE5C7C5B3 +15F42A98733F1D10EACE99D9E2E4568C245F3C03A243E7723C875D275D244F86 +97126117319CBF89B6D57159C0C97E4281734C12D6DA5D756E484AE8EC628AC9 +78C8B0E49CF86C2568D6B5750AA9E8B3BFE77B018DF1AA8632302097885F264E +385DB9C64DC178A31D2269204C78875705FEB7D845C813639739023CD378FF6D +28AEFDFB2B30640594E74BAE5D665C7D464D6346C316F2C82DC088A66183DE9A +365F21267322440203E832F52FF1050AD3661B850CDCFEAA89266E2010164EE6 +49B6C049DE557787500AD1EAA3A4FFE04813739B93EAD90D8AF4A901BD7D88F3 +4B57284EC8A9C81DD2C74E8BF9FC97B06FF5885E2296C86D00C7E6C99928E403 +8654E11820AB502B19070D3D4A1540E7F8627E3F1C921427DEED9BB053D34039 +3086BD5D33F1854AB736BA455479D9184DA55660C162E9922FE3C6D332614771 +B50D6CBA54AC8D901BB425A2E72BCF38F406E94A2AC948C9028229C371660FA3 +B2CE5D94D82B5559AA234F98747E60DFCC6CB50074584D09CDC1F122C1A53B12 +04F0E28E635BA0850ED6242200FED58C7E99B8F8BD385DE3C616765B66B7165E +1B088557DC0C20A107F805F129C052CC6EC4654826B6567AB7D9BAC23D343BE0 +E030E86195C3576E8FA2F005843CF59555B7ABFBF05B07D0E34E6C64CDFEBF64 +3147364746BD2083CB68B30C677BE23C278918A73E955DBE0578C42472C4060D +BE090E710A84F29AF4576E4F9E5F324B71B75C6635F52F8E68CC98FCEC5A6392 +8812A856BF3D9975503089AB0277594D85DC4387C3FA402A3FEEA2F3016F0303 +351146DE4C2C05F857A8172E78458C0D906EB513AC04634C1ACD171E09440DFA +BDC2BBCF0BE2F17258DF3E580A4C07EF36A67FEE2AA8CB6F21359B223A3C1F0B +D4BEBC10F1F14FDB555F3889543419CA01CD5FA51AF80BB6F08C67C432880FCA +5C922A7689EE4F6117D5DCD30858B0B9ED62F26167CD06639ABCC6C8452239E0 +C9747A97B023C51579B8CE639DF0B1F932D0E39FE6C0CC8100B21007AD07800A +2A68A95A68DACD1E311952FA9FBC544BC1180EBF3FADA486D8A8FB310183FA75 +A0217363F38D41A2A58B783ACAEBD59B75C9045359D1A42A1821717F7AEBA454 +3CD0289BD7474ADCC2F76EE6A056EE469834A7FBAC024EB49ABC18C1C96706E4 +CA1D426A6548EDA2B8A51DD4DE9F19F8B80B21BD41B3961E9AE59894FAB49C72 +198284AAD6D067ACB681798BFDF4AA25E550EF0E5A1B5E3180643B119E041865 +30E3CBBAF84F339FC734DC002A4ACE57CBA33AC903033ACC2A56319AF2C2961F +B5AA4B4E6D58D86D18EB268A9B4E806C13D9526D00F129E700F7561B1CA11F7F +6D0516B05FBCE8BAE2F29A6E75104061A253CAE53D6E4E6458BB45AE5EC7D8C2 +1FB57B4B2F8D1781808CDE1D549FCDBED939A07BC30F0FBF40C48FD1BA6D4CAD +97707201F0CF12D1B15E5C04F99E37EF95C722343DA6D303D1821DFF3BDA65A7 +1B86B0399FCA317CE0B92BF144515F332A40707676EB91B9E1A8FC283678EBE7 +16E85A8F29FD9197937D5D4900D8BDF772399E6FF176520E0CA4824969979C3D +CFCE27E0B95D9E9C55007626E9BBCAB579F4371932BC707A5E6D6F375449AA71 +3DF51A75DA2F7EACD19FB990CC40428F089364511C47402471E56159F7F20E64 +5DE1BDDAAD025CABE92E9FEACA2EF5AF5C85BF7AE461138EF7FEC3066F42C825 +E0AABAC179F9A609641AB2B1C0DAC92D4C2E8FD882590135233E7BC37CFF2DA9 +622F8B8A0946E32AAC35A3069D0FB90BD7B1ECDFD87D07DDBEE2857C74522BF4 +EAAFE072801F32374D3FB53A99160C3A3027CE745EAA94B3160D2EE677B4DF7F +D51C49063A552B5E6FBD03E78213EE97A394866DCEEEBB6308BB4D34B7F4DBEE +36FA3514D35254AA86CC3EFAE88C3F30D3C38CFEDCDCA8E0CA34C96145729C23 +7A2D623AF4F40A254C1C9DDAEBA83F464B7832423864B63F31AA58837C920804 +011A9768A77E87DD0822CB832707B51E840E13E06E6002DB41A3C9A6B6536146 +62CF68AE69F040A09E09E2AE5ABFF2A26D606CD08E1A180CDC1E439CB5C10B98 +1C6117987410DE057BAA2E7FCFB468F7115BA70164DC1DAE8EEB95C46C65BBCC +A63461B170D55832036A9CFE1333C56BBEFCAFDBD1EE68E5BA97E80C3587910C +47154BA2D06EF77AE06CFED0716D0F4A82932AE35AA4724C069C718E7A974DDF +386016899CB303777F997EFF71A1957B7BF017266C49AB7668C570451C1A8614 +0E4741C7A8BCA2078463A1D131F3E75CBBB575AC13FB139D01097C32FA14DB10 +798B803F36C905A5434E3201AE098FB39EC87294676C015C8F1E682C4499EE47 +7715B8F336DFA57D50C6C307006A9B734F936A6AE904B728829B3800D08EF5AC +99A90FD030FC88053E218989D6914630F711CA04FF17790130953C2044B3B51A +19CB91E5C6F671FE54BE8513389A681A32BA96A2184DAE7D7EA2770FF366CA22 +8536CB888DB331F9C069196BDD7A24F51A1C08693BCA30398008FE06FD01F251 +858D94FCD90870940E02D5CBD987596D82133D0732D12D62FAEAF6B27AB3839E +3BD4D724B33D4C2A5B400E929E6292EB3D54C7A256D7BDD7E5FBBE4C48D59E75 +585F946317FE740A4C835EBE7A006E74FA3B81D971104E6E87FE06B2DAAB9978 +35F1A8410A92ACA69548E84FB24970BC74D751742E8839C8E048462C38467064 +7242571A5804C1E69A090810A28642C144A6237776FF83601301B56E56C25FB3 +433DF2B03C8FEDCF6B0CC6F303F0C02E5F680A909A35C9BDC54BA2FE743AAD43 +30F9FFA5B9D073D840725B4C4D20FAB7B1C1F1AEDD9194DA893820C7F7DAA694 +68704F954ABDB8F27BE1E500E054F7A39A6433A2EC8B0ACABC41C07B902BF4BF +CC2E9F151C9B2F422077A99AA9E968C5438D4A1B11A55F8A1AE2633C998D6ECC +2388A7EBCE3C28147E8D867C2BA32D05C4CE3956C2093045473531C423FD4767 +BC1E5CC4F5742D262FCF797DDAC8CCF9D93C226C6E4680E614D7AE7D455B3632 +712DE0B77A46D6D634EE59B47D332766B8C2CAD4EDF3E30A3383A65A99CDDDDF +FA835C88D4CB7ED8FA11C3915B3DDD2375164EB617C1B14B019017BDA88F33F3 +97E717C7F4C415B1D7DCAADAEA62FEDD19ADD6BB14419EDD81740CDFB4AE3976 +F0013BC0574AE73178CA81CEBE438A847A885E9FF066FDC7C1AC4700283F404B +3869A901B2DBD29BE3E406922FD161496ABC3C17A094706517B2CA7F37DE0675 +4A6D6B9B893F98BF45137DBB898654F9DE9A4DD0CBA62BF3D3BB64CA731D075C +91F0573471AB57FA92350C5C685AEF0832AE4B2B6505C1361D4664BB37FEB482 +79B3E073D9CA0018C658E29E6C453ADA6A09B83D85A7C69814F439C96899E977 +8D66E375ADD165785106098FD562E204D9BEE5720D7AA0945DCD54EC39B0FA45 +F22CCDB717B137AF0472E1574CE886A6A536ECF5D6E56B02B1C9E824D66FC7FA +3F19BC401D3B79303B140C57775A3ED6A2B2731901F3B1DB215E6FA70BE03E7E +AAEF27B80B1C24523A3FAEFE16E510C1CD4BBA185D6817494946B997490420FA +A0F9868A42BEAD43395BD3D7AD45FD9CD8C7A4B8564587D3A0BD81D9141C5CF7 +D926334CB619FB45AB3E7A6D8BA9EEC58D5DF5DCB390D357DD439821E92B499B +868141358B5C0B99849BD7DB88F76119C83CF32D1F401A04C9D64722F3CCD410 +8AD0354234DEAC8916E88823FEA829F495F9AFEA7B78DE1C8A8FEF579F4976A2 +DE3F9F42B31B0866993643D7DD004D77FFC8D615B189B0A7BA4B11C0639C19A1 +ECA51D8C703FC01C17EA58621AF7815C1516216A90D4B88BC695547F7523DED5 +E46C085230B299992D46DE6CBAD5E9C095C42EC4F0AAFCC92C829758D4B76884 +27E48604749D7BCC57773D42AD2A8B759890536277A37AF23F261F3DB229E863 +9F4F4BB7E6AFC22A24ABE77886C05155760443A474D462377002F899328B8777 +1EAAA7809D6363F9BCBF1FC07A373829214BCDBB0902C1E65769F300D48A647B +A4E6DBCB93AFEBB315CE63072C4EC02B77CD57501135B8660554E51D18A08D4B +A2E78E3325AD08C8B0A24F6184ABD29242F05594C8A15D9E29F94D9ADF24D314 +55D407AFE4BD54B30EFB115091B1C261A2C3B504F1B47BEC757590445255B48A +D6F32E37444ABB5A63F5416423DBFB1F272351426B6E31CFE2E9672B83DF88F4 +0AF206849A3706D23B2AEF8235FFD2B48A31403F0AE014FB71ED0ADDD536C82B +A0A1A735423F1EF228DE2DDB3528D8DB5E5F501CFB13013CA491AD85E634DEBA +6AA2E2547ABE84FE25109997224EC3C8480D941521FBB5AC610963A9B2D60D38 +02993AA55ED964B4D6672A08343292D75F52EE8C6F2797F25C5DB17ACB8805E0 +5A4194FC3FD5529FF27CC9C2710B9BC8574220729E4E2C530D7817D814839FC2 +677720259841D034E5C449F42C0A5183B64A9DE959A40BFC7E76A480F65EA665 +2EEE2E558893A536A4F1E2D20B905943AE8CDB2BDC5D2FFD010375AA4337A75A +4C5C4A1BB5792E33AEDC93FF050802F521805F14D6E37365A0B3DA848BF18DB8 +77C99B5971F4B55E3F342DC7AE1FAC79DF955827876C5237FE22449DDF27A26C +AE32A85D051D4FF70DCCC70DF46985613E4864C9874B1B747550D455F133126C +BD3CCC12CE621638C42661EC231CE8D2CE153E143838C54C6F90D514E2D671DC +CE713CA984ACCDCAEA27F59B1AD73722B4D572784973E835577281A4C48ADB3A +D028D22548112083B6CBE43E6405158D3D0C4BC6C104BA72D382E96096C2BC67 +BD61A30CA0FB181D7C93782CE53DA7AB2DE1C1290BBAAC579A116137E9278245 +8572B1D5B9FC7A0ED4F3F55B79094A76A00EFD7AD167EC7DB148DA03E67C80B1 +D3D202E1C96B9F94499D896F8B975C07A25F1E75D7C69292C4F071439D52FB5E +8CFF4E333A9144F713F8D013828992D12CD0342F9E0701CCF52FCF584F8420AF +75EA7B4BFD6B3E9D8358AAC14CDE6A35D5C80E50EF63E1FE616DE7DC0657C1A7 +E0237C1487977880A4BA55F2A77A8723076844469F278228A4550C7590626C5D +15A8A0817887D3A07831CC0ECB5698AFB5668BA61AA099B573D87CBBD6F1C293 +ABA99F331285C688AB7DC85E3D25D39B6A5AA6A18699C0398C00AB0A65F0FA03 +2D996D834B88915F2B7225336A052FDE88AF0E4FDB08F959664C7647AB62AFA1 +0E03E94D1111CF809DD4464E663916C8E0CF5F293CC307D8CD1FF2719F26081C +8E523EDD8CC5FB2F8FC2395802440FC0EC2ADCDCAA72A75FBC011659024B4F85 +FEE2880A7E80F8BE4C538B404DF81A2122657D4D07A9EA53F6660FF757C377F7 +B7281F501EE7C71E486C8AA6AE5A22F7694F08E8593E926FB5CE60132DBDA6A6 +8635654FBD68B9B15E5183B08F8BC9C57F87F37B627463094A4C1597A40FEBDA +CEDF9F0FE9B7C34F67D477ED61DDE142B94AE7EE452C0C4FECFDE7103C3D4567 +68DF28E6CE328CB202230BF8D10691C0F0B42FFC2595B29F125B816EE0DF694B +DC0CDDDAE09586330591BD4E9C7F515F11B86C06C44BC13A79374771448DE9CF +829DB77BE22376CB5720938D5B16ACB959C52A2BFC6ED2DE07ED182F63C49562 +6CB2834F8ADD0B532B5E91F67F1A838CF979520485D605F684DF9D03FEF75721 +2DA53BA7EDDE557057D5B0EF4F476C8BEB7CB2CE930129EFB00DC86D101C0633 +B77585B6B42ECC2CB62758CF0833D9B941E9D46EE0CAF36F3503BCDCC7DFD183 +7D1372B9C53D56D98D1D04D85761E9DA026DA6F67A7821F9695C36185C577079 +2750DEF13CBC790A6CC6D26B20C3AB1ECFD15A376EC0388E2B21E9CF5EF4EDE8 +0637F7F0B069C910B7A8FB4A7A304791E9C7B235C3BEEC57C65DD6F0276AF51D +C7C4269504C7C176A361B468527DE2A3A705AF9697E16DD50ADBB0E84124E80D +67775545D05A 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 @@ -1937,357 +1937,353 @@ 23DE9D803FD6E8D846B3F729BD36137E834E016242CD2F7BF048959DD45AD413 19B985D05E5D422F3D0968375EA6A90FBEBF8B42B15F15280469D69629C08A42 1C298CC027CC288B9C984239ABB96B6A891C1360D08F9ECC22202861E4CE9B39 -8BF32D2E5635B6583D04BC0AA187D10FE773067ACF3B528CD412ED96902B0056 -567103E3FD911A099ADDB9EAEB3C08F1B36A918FE865B7DAE1C49F21650E65F0 -C6845C15740631BCB7618A3266D83E54976BCDC707883E531F3F833AD0DE88A0 -CDB84D8384602B992263C3C223D1B5393DC98C75EFF9AD8D98A764228C70A303 -28D87B1A5510A579D01088C26D9667DB86F72FA302A3A8EEF7E05DD1835E72C0 -66A0728CB0DD8C34BA1D772886333BC78C79374026347FAC9CED39B7FBA84DEC -E70EABA29B80B4E813C0E6D5ECA5E9ECDF0413AF7556EA458C3C3B49A4B14A05 -3034C04E1F8665532D053F810683C957050FCF44C5D4040CF09893DBF641D68C -0969D67BEBBA6DA451D446DCF87B8243365E7158D89332FB33CA28F0A83A7A63 -D22A0948A46F0AB9B2CDECECDA40FA75B046CED41C017FF79FBD7380CF33D726 -B03304BF8EE1EE450C065BC8B83643AA74F8D45924181D1D0C52CE78C36DFE66 -99CFBD08406AB9FDCC61242472612AF009F8625C966AC9A7228B85912CA77A9C -832F9D14190A1DC798D4E99B5D067A020FAD7E13E2E5A155A94E46853CB93619 -39183DAAB590F1BE12C3C4B0209A93CB015E58EEA72C0F71E68EDF1CAD4CA776 -9320076D70BD2874A166F2CF735BD5154F9FBB219C868A568A7C176060F78092 -1E3661E66B7E0A8DCF294E09D487AD7F7D1ABEF83E7E0E5BDC60D672A4D8F5A2 -4C33479DB4FB7105158E19C62FB0E1B9749E6A9D4BFDF7884B1922C4C48265FB -7851C1116696C02337B64F1A0445396102B541EE1CA10D8311F79CC58F2106D0 -12FF6B1D274B810AF318BEF04467B5066889896BBF019F63DD5DAC53EDB1CD7F -AD10D90B2D3CE615546860B11AFD0D6B705DAC7545579DDD3ED867F31615CF4E -F3E4BBD8527C9C3CB4DEBE71F1AC965A69A1C6E244BD5A49FC81135A587EA904 -A863FF7D421C407EDE08825D78924635E6968CAC4399D231C785C9048FD8C916 -0B2676DB4D91487B862B25F68DBBD03B604BD875420565855CCBEF9AF0793964 -4FD45E490EFE697A470FA3C60192E660C45083E27B9E569DD1DBE07706975B9C -9AF2851279A7630999C92E9867F55D56CBBA0CA13A0F041CD0F3ADB318A0D298 -ED48F8288691BB2CE08B6A73E9FA89DAF661F201947BD64C1EB769EA3A0C6FC0 -3DC343AEF2379881E46627AD2F653B4C6BC37E8D8452C3A7E399C0B6B3D93671 -F51A92EEA7712A872D0BEBEBB071C83D9254A24C8799CCB5D2FF4DB31075483F -3743AE4BD1CEECE6B9432BB89399FE62B87DAB3B19FA924FCC1F6C3DCA1B0049 -51024011B8670DCE537387069A8732AC4ADDD77B2A0D5D97105810854595C4E8 -0663FD917B5B587B8ADA22351D79F5E5AD494FADE90336AFC27FF9FE8BC770D6 -0A8D6FBE6E45B3D4DB20E91A53D84C8B100813CEB9A81B03E142748475EEE77A -892B3458A3AAD744A20ACD28C7AA6C5A996C9A9900F2D6B3C1169DF3BF2B1A9A -56EF83195431EE89A89CCA5A0EB6A59D7D89179B6C127BA0981FE0122E4184A8 -FA9094D9C3D54BB7CBA31FD03C7048A09AE67C956A5363F5D51ABB19CA264D9D -5D515F61DBD9C35D259950530A95350A313CFA8CF06413ABEF844771BF99590E -F9A2F28975AFD00D700E83A59A3F0B7238CC74A8C1C9DB059C84DD91F1E07580 -C4C1311FF1C4AF2AFAA07CDCE72B0928663109CB31DE1548C72EA321F0EAFE9A -ACE0E0BBD840254E30D9A46162DACC79A07F21BA056BD90AD312A2D728CB94F5 -FDD65516843523741D2430C5338FDB4274162B8C0409ABF94581C1A3D8636BCB -78A98069466C0C869BA08047E9C154DC6FF00A1DDCC2C4AF4D5DA5437BD02616 -C0139731CAA7817984BE614D6D41E9C21AEA1CBC9E56C783F68364023CB95387 -C71A72D9DCD59222964D04650181988D140295091175DD985F5B53B070D20B89 -5E4B621C848C9370E0687B45EB1070A688A94BE949D242AA6266ED2D64C2518C -4A5E75442F030E137D2E3BD654C4E4EDAFF7B46EEDCC9090D537B6CE01DD6D0F -1872A47A04ECDED2421B511118B0628148D2289B74B79B3A68CA7A2547D644B5 -2ABB83CBBFFE319957FD2189E272DA2C2E35DACA8EE229F37EB4C94C920A65C7 -165A2ACFF7B92CE4338F3030E157CC75281E1F33AF00386FBE6003C4C8CDB57C -4EA70A31E2CD15FE6732F98BE47354C2F92AF632B5BA1C7ACCA3633ED13919BA -106E6ABCBDC11006BA4560AFB17C7091BC1A632E7870B65717656A89EE550576 -B5D3BD5DD829886BA59D186770871C3D293EBED70D66EE3AEA926F2AE6AC6CEE -30CE46B99DCEA2D15384C53D08C6F1A083A24C025D92832E16E816B893B3F2F6 -68BDF430788D1167B14633E0AD0FD74951C5826BE0F4B8CDD23CFAA88907C43D -1678FB2C4053E0E2056BC4B33F36A896D1BC212B0262B6CB59AB3A5ADCC027C9 -EA6A2C0F1EA2DC6B88517BF08AF54C9B1A4A7B0A4BB9A66ABECB539BB6BA1F9F -313F2A5619949D0FEF977DFB87ABB8B8DD420F3097B2B8BEC00EA5A3E8C207CF -508C7CA5133CA63B98A14E11FB57BB7C461D7C8C767DB10E68BCEA1D5A4B7F29 -7AE639BFD660B1CFC78DEF00CD1278833E48A65BE281C9438976BBB475AC6818 -C533FB4D2F4D3727B68F533D03554393D66FEFDAD1A3BE79FCEF05B98A5D9EF3 -71F4D16E531408B2D866286CB89B50DAAE9978B96C8BEA869F9E90B780F0C98C -1618C4F6FDDA21820BBA795B0AF3D00F96635FC5062544317A62A37060F965CF -3BF8A9C7B5C3D74914E0AF04AFFDA0FB1D1E644E2FB8125E94C480B4ED41FF6B -DE326A771B82A9C44B4DAA194D3C2A8855CA293787D7D5F466A2587860B64408 -6F14F78C085F63E6B63AC41FE7574E5E22C723202B7D42A1BE0D14A299231F75 -66FB900C2A030D0E09EF5107F9905A5C66E6A5648FBA2B8E80217160EB797496 -FE3D4904C8E3B6FDE528D1B931C369AE5115114B3701CD40B57457341D735576 -ABE1907500771C3EC5F562B63DCA85FAF5769ABF0F8F74A678E508A59802F1E1 -B11545E6C8697D1A7FBD4ED7A5DE57778DF66E04AD354E5A45E199615C6CBFC7 -7F6C232D710E8CD5F9953DDFE922B2CF50F02F65A96E1BEF0C1FE6B5C52415B9 -052B9C062B532A6B83260D13AB6D3B2A48D780E03B4519F4A2152B82D1A90359 -7CC62EBC5F26608232CDB89D2CD44F0E889AF80B1A9F8C0B9DE0EED9787D70AA -AFE3DEF464503D9E56674C9BCD0BC65876F2F455C83412E8FCAC08ADE7F8E2AE -CDA7A57425C7ACEF0D58CC85F71D8512B32D9C06AC001382A4095FEA02E2BF2B -A7EB6C298B10CD398780A7120CE9A31DE391C349AA273C890F620172CC434C23 -33265359372A5451C4DACF0C859BA6D37AAAADD08D2F85DCDA2399D894840D7D -AD9870DD307B9D602661D7ACA2F84FAFDFFABF5A89AFA9973161DC1CF3A3943D -CB84A9C241C8B6D6CBAFD2DDC75166C3C2D5994DF4D2C60739F34E7805582A15 -76191F4150309E55FA04EF8A59C4DF8EF1C95E57F0C255B63C82A7775D4CF3BD -A3C56600BB869D411A5ABE7EC6C67437B328DFF2F2BD6267A43D69B6788802B9 -249DAE42336C2A3DE75816951644C742C36C51F120943DE8B75052EE4405A346 -E157546DCB7D845D81AEB84E70B857B9152C3FA6D5F3BAEC8611C14F67B54DAC -F58BBDBAD4C473C0DA872330902A46610865EB0EF8F97078841AF74758F0E6E6 -3DBA2B1659FB937AADD1C8A612C61F0C1A9636F0624E64D6D92966D892F44F09 -48A4BDFC9A83C267ACEF143585C51ED45F59126AF7EBCEC2B9584B0FC6C1E670 -FC382E476B6C33071A9FD3FC2D0F943DBE055BAEDAD6702DC0F474F9B2DAFFFB -C0AF48B326EC447E31210586B7DCD517FB61F4D4870A5E467492F40CCEAA4F2D -B06BF4FD8B31D9650D032A0A28E1D413162C649352784A0414C474A82DC471FF -1FFBDAE7795DDB8BF3DF22C393E939F5634C540DFE2590D71BC1444BBD79A9D9 -7261CAC5207814AAA58D8B135A52A3D3174110FAE364257A6F79AB3B73B52A0A -EF08DC05593BD0327BEA4697339E45996E5D6812D166165790D8E4543C130DC5 -34725E44BB037555803390CAF9F94FD6BC08AFC3ACE747B9728D8CF0128D5B4E -1275C4BD7E50AB5F980DB3C3281E3FC4A500FC6DD0038D35F4F5589679647238 -FD7EE68BFA9AE20EB140B7277073E6F26C7EF556FD311D510C92E89B70762F42 -410ED318AFD46F66F605E98D1EF12F00727B3B3F21F695241B4B5863FB1C27E9 -6BBD4365B9AEEFE8A18AFE350731AAA0ED817498539433027D50C8D38284E888 -1E6A1E6CD54F851B264E2FC4597A6A4FE03C7CFFF7D1F75CEF43E97B22096A1B -D8BE2DC4A899E64492359B346D9C0051361B6AE9DF079BDF21FBD274597B3C02 -4D0FB1C66B8AE0AAFCE0C1CAC54BEFE069C0BE9505EB0B1AE60869B63C396698 -EF594E1C8E5995AD22DAD027BDBA4BF2FA9B570E8F0FA3CAEECEF6DB8C4819E4 -AEBD7165A655F1B7828527DCA9D01324FBFEEDD6797C8E3E9E17B760C70D7AF8 -8EC0AEBBB2C448DFDA6B6B4BEB43291772174F1C369DBD1C4183C8E00A4DB46F -208C324163E0BDE572A84B85393892545249DB26457AF5FB311CD5EAA11D7F9C -3E491B0D49C77898AD873381077DF84EF4498C012D7752B22F0660810B6EC0F8 -B66D447775AD659C51D3893CD2B4509E8B9D1413A99527F720571784E7B9302B -92175F1FCA726E8AD6D82B9B7E853FFA5739D0DE0A02BB115DABF83B1E4DE706 -C23532EE82BD57109F9A7A4E6A87DB4FF5C698B04003312F1BA23AEEE22162EF -F22F7D338554AB08625B26D74F7D23772532A371AEDA9CC2962B0B665393FF04 -0B032502628AC491E593D0D450757AB016B2C74C6AD44594E0FEC2F880B578CB -5C4D6A409FD6B64B9F1BD7CD8B69676814D169609D2ADB2F1E98F6C8F1A16D90 -63FEB3C8FC663DE0CCA1C5CFF03828FD1DF28678492DA710EA61B9096A173CA5 -FA8A85DCE00EA42ACCA03EF856F3F17FA32A69DF9F73C46944705C5DC20A7535 -34CCC3878E878A0BAC55B7D56CE2C43C102D0AB841BD4A3C5EA0379D321413C8 -6C2DF639D4EEA521E0A1C68D8B60319EB999707001795562E8AED4ABFAA486FD -C11D4F12ED45A04DC72264A882C97510C91F2DD77E3D5685DB2CE52C4746F613 -AD98EF16AA9773CB00735151B7D4B9315441BC3B8BDDA5ACF619F49B6052AFAB -0F19D9ACFC8D6E0CA79A25A8360F9749EF39FB60404E318BB1A98EEAD98FA0E8 -40DFD76BC3A84404F7D3904BFB2EE3597D8364EA556E4F7D18F32F1D86D10287 -8AE46984461ED91AE22B6EFE0CE5511921B539122DA3EB48707B8ABFCCF2E6F3 -9408D626EBD0C2A1A87827ABAAF02873B675AB54BC6CB5B40E697471320BB686 -9D845AD686DCA663AB31B4C2A1915C55A814FBA82E77736F7F258C1AE7B42449 -FD341CE08D65E648A3FB4DE280353F79FD70578A0C38C963461BE98100EE4084 -CC1DEF4E35B10BB81C632FF1AB4511B80C881A729EAB34C9E9D217E3A57EFC52 -6B73AAB4911830A00BA599013AD3BB83BD3DBC7445C316172B3B8A22B8148ADC -FF33379CBA195094D2C2CCAE0E260D8DFEC35153BB3533BE014F456A108C9D62 -5C21C1BCD3CB9D7AA0DB74AE571A88AF6BEDDB6DE3DAF92AE60187819E8EB8A6 -7CC1CCBB5F23E63A107EC8143F0F69B62CFC95605231FE605A989407218AE464 -C2B566EB86E1075B0D8FF788B726FDA5F5F2D8743C39224C2231A46426F3B6AC -747E69C46AC322733DC052641526E775F10924F0AF404C37BD47369986746AEE -ECC7CAAC1B2CF6E5D86A46F4F6AAA2BB7707BA4D89F1B46DA3024A84228E1A5C -BA5EDB68205AE6971A255381FC06BC03644D67B082FD503F502B28141D437C84 -E809F5C78BA5FBD5B8D51C012C3EFCA915505897C8099F0938EC15464FF4EAAD -2012A1239E0251BB126F4E400C170BD1C47656CC010235236733633CE22A43D6 -3E043B687B32BAC9EDB90DEA0D0B0015E8C1DE4EE0B0E0C10F2F50F4E35B31BC -915A1D984614AC0B10AF2FF1B28FC135D07072C0530C50FB6ABEBC1592CAB0C7 -2FF36245ECB609DD787852E5509AA57B3EC5F6186B16A4EF52ADF58D7ECD1D34 -B2BDC2BA556F7915F5293A8CB3F44E707A57F6CDBD91E90F9146874311F25B80 -A7348FA90D09459843F842FCCECFE4025D12B2BF2B61CA32E6F72B8618390560 -0157F80C82BC6A54B9F0289215D94C662CCFA55EFD0650B0ED761D98C65BD47C -F7CD595FEF1C7DA57F3B79FD55ABBCE8D30B1D0DE32994D52F8885A87F0C109B -D90052BCEF87DE36DB4A852E910C792C094D0D0228C53D20ADA83280C79E9100 -8AF8888CAB9835D6CE65D7FE36B18F365C4F6324DD5670157B37AF55B205F460 -D10A0D16CDCDA78539CF166ACECEF425A1740B7C8F02D13F2A86070416AD9AF7 -BD30314C6DC920E3CB78117564ABB1195397CD66FC92F54B5F1535C15E02F763 -C92A2F3F4CD1FEAD965306DF3614D0362B0191492905777B75D8D1C6F5064A1F -111B7EFE43756B4F0996030C00503EFC5351D388C150BEC0FDA5AB0E218423E5 -78F87F1B7684AFA6DC450EF115ACF8AC2C8DFF33AD39FEA1008A46EA9D6BABBF -B5F220B209770EF010154C87A4BC067315192ACEECE255BC6A5896C2F4963170 -576E250C3F8520E1E413A30A1C17F50F6E8D2DD87EC02320176F355709D75320 -D1747ABB9EA215793CAF3BDAC8F5C0812A630FE85D7FFC3AD199E5D83B068C44 -B757C8A127C3993C01E25FD94725415298FCFA762ED456DD7DBEDDA2F7AB71E6 -A289E0F59FAF62E3A2CB6A0995CC06838C8F9A6E19226B0E0953E2BA3764BBDC -257212FA3143D2B67D308AD49A0B245F0A97B09919C307B326D575F1F865ADBC -E292206795305174C193A4CABB0044936E51BF95D0B13E81F2C64248F1D9749E -CEC22448489B2AC1D766933B570E3471B4917ECB1D66E0A4779B084B1D22074D -108867FEC1329F5B30FA344C19FABB7C09A50F49A5B0A1C42413B3ED9FC39B36 -500AD32B07AEE4A5C0DFE29DAC2C6FEC431842A473EB710293F23774FB448E51 -3EB6B4A27D98078B2A4DF3A5F0F41308374765C86C0A879641FAD025EB77D7BC -9328E717E2EE4AEF31A3FD23573DDB8E81F20F6499FC2BB4C94D3F1054785E0E -6F3B8D6176EDA6E386FCBB034F6E82F6FE43CB83AA1147B05D51BBB03C477F54 -38FC98086DE0E04722C5F0CBF9270E0DFB928EC7387710118513A3C97C0D6A9C -D67BBC5AA5DA3A33BB0F534096582355E0B3BFF7E6536FBF496FE4E05F006F88 -C7C28672CC58838790821AA48534FCFB8DFD4EBA9C94E4F50E0B9E046651F779 -E11B8915503682E7FDD90F05DFFCC5A009CE64FBBD223E2634DC95803805F4D1 -C27B4D543FA3EF2B222DAAACF40C526B2A1563C0968E7F2FB22489810A530519 -100FB442B5F972F960FF6BD86A19A1F297F93DDFF83CE2347EA3F861596B961D -4FEDC423B8262ED0F0352DA19F07ED09117CA72EFF0CA7B666EA45493D1E1317 -559D4B5D278F107042D276C9AFA6A093ED696867BC1041E5F25B11C1687C8C1A -72DB2FCD4B632FC212D774785F2D3579BC0DBDDBC8CCFBCF7B686ED3BD92D4F5 -378CDE86406399B059198B66E88BB9EF7E572C6460C36B0F2FA3E19AC56F93EE -60F1F7BCE76F0AF284C3F41C8BB69F7D34B4644AECA4E9324CE2EE4E4044F4EE -7B9C28E8B454D894445AB47B05F7B4B94529808A007A5E3A7D323F661F9D9C0B -B5BF1C24FAE9D951AF26493C3C9302C4C040A33E94E6596246511185628C7A02 -15D33184493337E2543B1D82FD5ABF4F47E894E809C51DE0ABE163D378910FF1 -717FA82AD420E076611F5559AA027F1F82433B4B103CC1541D342330D9BE4592 -9B9112E1FAACB0FFD59326ABB3A352C54D097E0B79A91A0CB39B77AABC40D191 -C895ECDE7E9439DD2098E2D81E56F13F178CB8DFDCA5759C4580BF1DCF7AA3AE -83F2D998FF3B9789DDD4B2A3E1F5CEEEAB48CB410F5C07DD3FBB4C362BE0D32B -5BEA9A428692EC6585A20F11A5C73FA22D023131B1B416AC0B2F4A4C801863BB -D43B180F82391830064FBCC5A233E3ABC5B30C1FF8155C61E589604EC6C16E48 -F3C676C95C57B8E9D4305C1B1C7ECD75B3A5C7F8B8849AA1B46FDDD928D92B21 -D0B6FFBAD0B71D101EC153669E32324C497CD26093D0D2E4AA197F9D5E459C50 -709C64D20552A3B9DA9475D3658C302B5E7EAE0DAD3F9270A327A6644AF5C3FB -8338C062F33478E38E82C09510F27C2FD1FB2D304355F28B35C9EDFA0AAED925 -F2D1493BECA291483EB47FF0442C3692D29D10FA92ADF3C9AD85D5AC09D35949 -166DBEBAF7D425DBDF179F8BCF21912C5A2123E869DE9A9CEB4803F2C04414BE -45DF573DB40F5B9E42406F49862C7B23826CCCB05E76BA23BAA5A17CDA93D4EB -59569951158FC068E32ABDD8930D6C4C58A7DE1D39030E3B818E3382938F466E -47E8189A6B902AEE4798286CF0C032E0F2AD018380C904C2F4EC61ED98CCDF25 -9E2C691BE9812FD5E0CE01F2C94134C9F0C05F4B7F1260DEC20B9907E1B5D372 -8677FB4F0485ED87A3F6EA1A647072D635F7E2838649CFE37A4FF8182882BF7E -9474583F4E9D3548795E0A63D4859BD27B662D156DD893B3799371DB1BC75A38 -0F454EBF825D683CF2CBC8B308AEE9D8FF8EBB8A7DEA067AEFE8CC77331156CB -20210ADE2B5DD0A9F77BB6E98F3630800BF33915E73E515B34E58516D1AD87B5 -00A8969EE2595D2365AD69FA4F67CCAA7D243B8D03FB39CA136DC1E5FD434750 -8A329F7D11DC4D33F6A0BEC9A23E5EE1A18FD5C3640E3F30FC2D8CCE5630E618 -A273CACED00DA6F094148C5D6751DD983A2823418223E715DBE8ED167B2D1999 -650D0FD8685884BCF1D6147C162BDBBB6597DCEAED3B5CAA75F301D46F2F770A -CA1C8997E99D16CC0A58572FE1D68383D87335A38AF8C27556FF19CC421B8BE1 -8AF89CDBB98273BF4E43025A710B4ACB5D7F2C77249CF1756282B74CE43F037B -F62DEC52EA41330A2783B5E64F72392EE25FCE9A7E872F4A9AA7BB41E5368888 -6DC531A2E602696EDA1CD3DCF808F62176E9198AAE9CA8925038D41E17570FD2 -E976F627F7213AC8EE1B2BC240871B7CC1C61B81BAA031B8396536AA62A67DE7 -63FBDFCFD363DB5CE786230B302B786A859C48BBA8CC27EADB1FBC84F1059FA1 -3A02148B4CEF5DA6D90664E72DC6F3EA267E4102102F18D79FFBE4E2A642E94E -F3D9376838236476B1030A0C47D28F4E7EF6358D213AC0A95391659FE736010D -355826A83F7FBEDF3164FF177C16C41789E84F375C6FEFEA767DF654B0533E98 -A1430FEE50F41D39D41DC2ED6EA7EE1FCAB31FCE526D5556E89D36F3B402C5E1 -C0CCEAFA157772B77556AAC8F874A019EAE0A797BCF85655A7834D4DC32D388F -F3E48C0F7B338BBA1C9E949C5C0BC1A727A77FEBE57E1421FF81FE4AA81869FE -86EF313CAD75613726AB3F7508BC904A7E55F092A16D605802D36509525EE2E0 -18B8CE25A0BEC74D167F9E766E30C4EB0D7914F4DA044FD895F3A9C196E23256 -9033CF1E352E82193458B6CFD32238CC93CCBB0E05E8E6AED8CB27157BB148C5 -C644977C16D7F4FC50DA22A28CF8F945B5E0209C8D715E8E7D9D80F32FEACD13 -E6928F4BB60E9684C0F865C9D0C2EEA5EDB0A355FB16426A2405D124F3A01977 -1DE108F66E30EE01ECAA74FE0DEC9A6D485B084FA8A38EC3A59B23FD35B72F87 -ABC6B7D73EDA44DEAC4AA7285D15339EAC0B54B52FEC5B7EA723622704A3DE1C -AAD548509991E18B3AD4CAC7FCBA320ED3989A185CAFA4E22A42E1B5C209F774 -F5FDE4CF0FD23978F3C37BC3EB97A0AA9B9CBC66538FF705F8F7E2C3CD58A359 -40958DC811EBBD7F16902417BC1C97C3D409E4039E0569C6826D22923806BBCA -E601CFEB9B249597BF69BB74FA9607EA9CAC2DE0C8B958574B715D64D5E2AE19 -DF262825913DE26CB598B36E6F8168F7641A58018B9ADBF73237113B9FBB958F -1A3CF592672A51EE2463CD7F22F058597DB9C7316CCD49EFAEFB6A20646E0DDF -794C0A9DFB62A42FC95483D7F578BA3163317AEB14561F49F6E2A909B7C92370 -2592FF0614A1AAB9AC39E93A2DE2D38330AA56BD51D1FD225D0DDA8E91B94267 -127CADEC25E9769512EE28557E051F516329445C31D75E19711CEFDF77224F25 -8B590ABB3BCACF4C3620142B0401F7218BA00C67A748A2DA5F784EF53521F536 -7110D64B659B7BCD26E03F6D35A6EA3452A8F33B4A4E580AEDBC83E7D882BF65 -AACBDB77189BD88AD8A0CAB62EA74CD673A9B37AD1C40065C309BB399045594D -7BCACB882630E12489BD5E049F217C8498287D768B4D0BF904BF0BE1C6340D18 -C14229DE0AC87C1FB28EAF752A2C88FB5B80A4EA1066F11DD918A2FB2E18DBD8 -384E38D2B645EB843A019723C71FEA7C4D02621308D92FD72A10522EFB409D8B -9A5E51F4AA9D768ED428750A6F34FBFEF6FDBF163B13F6FF96450BC2DE22D65D -F7F0F5223CFD29524C61D0070228ED1113C58F48FA3154E53E67567B46F7040F -B03DAD476D4B4A2705ED9521BD22F48AE00AD101CD53BD79B7172ADBB6D4C4CD -951D9CB787F957A1177A7F967A3B867D48A74A0EFF9ACB491BAAB6C997896895 -2F3A1DCFFDC2D71659F916C1630ECE089BF7318201DAEE72972A8AFD0C69D5BE -B5DBBF85ACF39AEEEB8CD634A58D4AD84A49E75E39A5799D53DDAACB7CC08310 -23D44AEEC34D256B1C6C208CF20E986B5F52A866FBE4221FF02A77459AA91933 -4DDA62FD7070BBA306D113FFE2F96090AD748C09470FEB4FFD0CF8C72EA68FB9 -3F00F3F93A56DE5659A40ECAFEDF5E3CF327CBF8DAC7DF31F0F02EC416863D12 -2787C56399B9BE4AB5DEF7D7E185FF02521844F75C48D1ADEA4C0D8436B3A780 -8A55EB846C5CFFFC5D207B0F269DB3DAA7E06FFFAD34ED5A49BFFE73CAA09B6D -AF0C693F71CE69B77FC1378A3C4790CBE8B5546FFF134AE8CB103DD6376EF16E -03501532E3F725E58F36089E3718C635EF95FE9921EEDB08F0CFAEDDFBFB3336 -517AE8ECA540F6918563EAB9D1B5E5BFFAAADC83D0867125E2050A05EF871ED8 -CD0AAACE7D95D37065EA0C92E46115A732F468AA43FF12337839C206157A96BF -A8DFD01BFDF8E2D76E4D46C5B9AEF23193156FE4B535C6155F79149384737DB6 -BAFDB4DC69A64056EEE87A1186B137B6D9D394EB8811AADAE996D67EC403083A -86771A4CDF9AC65678A65DCF46CD1EA9CBE4C1D839CD7F166BA2CA8521F698FD -4CDEF798D360867ADC4C8FD100DC3AB3B62C5BF2527A688D3DB498AB5F407879 -970F2EF1EEBDBC4521CFCBC3E621F992F3EAD3E9737976CDB56596E661129545 -2EBE036A72F668E809D454DACA709F2C0531CCB26910652CCBF94EFC3A4B3852 -B144EB820877E7A55B33B3E9B2B1786729B0643517AD956A7A4779334D0A342A -3DD38F70100854C0B3032397BCDA640CD12C985BB2B5835AA83D442166613350 -BACB4CA9F706141A9E9EB3DFF314B1A82113CA28B74B6603D67AA2D15A36972B -1D8B0057D3D8EB92A1809023EB95762577BD753193DCAF7021366943AFF53A8B -A9ECCB74BF27EE70B1D0B73078CA5CB5AACC1BEE0A61A75981F8A0A3253035FA -1D5D6A1D47DF111693DD9A1D35D9B865C06BD05A688B0D9BC285C0EBB1DF7B2F -2CEA26CFF7583EFED470D4BF02CAE6E4CCFE5347F61F669BF8E82ECD2112E672 -86D10C529DDB600B5237C11BEE28BC3120A0E212E2ED4F52BDF6980675D7DE7C -89FBE11E19865B1C163EE5F4D410F95A434056202DB1BDD10B3A75FA3C091D5B -E3E2F888A6509E1755BFB39F9EE35AEACEDE970EAF42BBFB0D441BED621A8E20 -F504AAB0F511661754B03BFBDEE9E5D704B1FFC70E429E97B8C5651C90044269 -58BB39683838446D49507DCB70AB0DEDEFB73F05E621BC7371D21465AC659AA8 -90786F8CF2A0B0ECA4B40774D7143F92F2B0A95417C475DA5308B5BDCEC67A74 -A425CD76801FF2E115FA3A95818D088392C84FCBC00D3B3C7D683253414D4C5D -74446BBFD130AC89A0C9B68BB1CD772A1BFE8776D0772ED8C00C13C8D0412D7B -526A73A0E38885B79551DAC3E1060537C0EE8FFE574C4B9E8155E2CD83FD85BE -191BDD6ACAEE898A02717A9725196FA59E41FB45D2733CE77289FD178AF07D7A -FEF8D6BABC7DA5425A45AB8EF3C2E369432252E497B172A6FFD4D3DD957C0E26 -0D3D402EAD21FB3E404DB8082DF2ED2C300A0AEC0DA12B7FB571F415017D44E2 -57509A41CFC2284455635F50F06937D23699B43084728FCA9DD25A7264B9D1F4 -2E086976B56237887470653AC62DE323911A64507B40DBF281BB060AE635F37D -BB4F9EF7456EF62EAACAB52F0606DFA777D2965BF03D7CDA312AE654EBFA92C7 -580B7C2A2E604389152704BDF3008ED2F58200D825D0F60C7BF39AF14816B2DA -5738DE7338132B7E7E92424B7FDFB15D8E1EC176CBB7E15F3FA064CF04E357DC -72FDD1E8AF8079B1134EAE3E5CB6A7262994C71714691E8BD7CFF2676EA4D0C2 -A5FCD6C622B3B34469E3B2FCD810AE0252B2814EB02C544B0458CF12DAACAC5F -4A2E078844AC2AC74543F4763CDC6FC081073CD60E276AA6E7F1D948EFA02C23 -2FC1567CD952C837AA1ABD3E3077F5AA7F9986F01B0A9EE91C0EEA3895260CB6 -3B4EA5F58F8C8C23D42C81764E72399D2EDF40C8F18EFAF113AD16E753263943 -55EEC4F01AA885DCBCDB7C9E251210AB2B9382EE45050CC1184F592BBD65D6FD -44D9EA6BC7583CA725A1DCD28EA77A085B0A47CFCF5A847C5D29C4F64F2A17DB -BEAD7B3BA43BAF8548B65DFB4814135A2A789E7E76C978DEAE0138AF8A0AE4BD -B4D22A02C169BB0DA5215B2B91A10ED3A2A9797E5C5FBD11BB295B02C7498B13 -6D90D8CD79D4606007D408E8D336D75D42519BACFB7164C2797F0E9FCD98F178 -D82372F263BAF8B2D1F185E549BA63428E2B8DBCCDD243AD605DD10666F367C2 -3EB98C9157E068FCAB8D91AF9683EEE87A1158A562C911574136CFC172D50C4F -70BC388C728E821395579A081CC946F528CE6F3471B7615F67623F9138DF8FD0 -CAADC4E42AEBF892B36AC169C716DDA724300E9378B809DC6739929C3108A812 -F9C116118E9AE1B066E1928A4A442CE02B2D3BFE18D406AAAC1603E754224AEE -1B802E92CCDCDEF94BAA8955F389B7565AB67D73CED601FA7BFF438717EAD65B -449941F0C87F048B9186C9C78A3D43A3D4C372B5F8DA74DAE6DD2A2816E44303 -790F04C13F08E0815B43FCD837A67BF4A2A86FECB6ED6FFA56018961A0C528FB -472971A8E4C47C974DE12133616F3CBBFA20CE57B572F751649D9AE64A61F271 -0DDE783CF2509DFC2ED2CE7467574AAF79101D56D3D2664DDA30FC7DD5B5C6B7 -0BD084CA516A72E6D3F8B7FEDF0F11EF9CA594C2318EEA3CC266A2F4C2F2AC2C -AB1ABDC5F7419F46308865F1FA63CF2AF4AEBB8319372B3305AA052477ACD838 -7A35218A6CD4A7C0ADE0C3F8B005D6E30C8A208A3518C1134DC34D0E64F804A4 -258A995097F17642E97FE9CC38A34C250B8828B4FBA1840EECBD06D427FE7E10 -4EFAFEBBC934AA295E12F25D6FA3D277C7C88DA60D818A8A303364BD6B2C0288 -6E94BD8E474F28BFB951BE4ABC493AB0EA6EFF110193105DF8E9CEAE1CE549D0 -A907F7A7CF1AD20E121FA6547F93CC10D7957B36ACAF213EE436C92A00AB1A24 -540E535440938E748DAA6401133235D1CC74EC8FF80F9E297FB6C56C12B4E0A4 -D53AB28F11618F2C793F6EACB593E56B8370ED5CFF467B5FFF04AD11BC5A3AF0 -A6EF110B540CD2C87070FFCA3AA0776FF070C384BCDACB0FBD4921C06E24C8F0 -CE590D788FB8C1BCF9E083B4778818F92269C274B0CC6565E2D70FFFA2480381 -040C5CA012341D51427A59C3FC9B5121956B4323872E67BA499876052131B266 -C21F0B8B37902C7C3156FAEB668AE6A7851BC7AA62FE60D792B35B6A38183B23 -E5FB11DBBAF1E60B0D9DF0E84B9EA6F1EA6C37B84736FE657F4A29E92F7DD89D -3473C81FD7F595770BA69C91DAA3154425278D323C3E50A14FF72A02BF3820D6 -6621B91A96A1D2F76710143D41C8305E02810780D868D822DC6056DFA4690F24 -90BE5BB4F14902B97F5FB4CF31A6C8B346A76B95D82EEF610AAFF9F6B88E782C -F0E46DD18BD1CD53C92075AFEA0C1F0870DA52455847B22A638DABEA04C90ACF -0D89E8345F118E5E26A3934AC0C0C9F1269946E17F1AF5759123CE2359B60ED6 -3FB22A23380A34DF818CDA8570B36B92C4634A80AA4ABEFFFE36865AFB384DA8 -70E5CB4829052F8BEB962841C2030BBBF874EDEFE149EB8A38DE0ED59903FCBC -25788EFBB825265AFD7FF2F8D5F9A947EA94A368C52986E8640A6D6A11B14DFD -CF435B2F1F7C168D1E9C7B84B2C2D9E235DC59799B99971FE9E6D9780EAC653C -981FBDF083B949310FF20F7B383BD10737136E88B9D294677C7C63CC50A41AC1 -B4649631134034DB9FF76E0B19799396A232809A5BE397B63B528A0E860D38AD -A90BF0D4246F012E19CEABC74F21E2BD46FACF96D5F033B6023A98DA51653D59 -C306875AA02EDC3DB78060D72B0A00596BE36367A1681ECFEEFA447DB8DE6879 -18962C974B55038A8F67AA553ECD27C6C72D46CEADA75D68D7DACB40B063F9F7 -464401B0AE4CC61A1F55A7E40FBD0FEB890DD2FE36D9641E40BD2F6D20C54353 -C3B282E7F46D61EF3A41F8BCB31FA38EE2B99B671841DA2FAD644C11AE20B6F8 -C7D5D99806643412273F874273FBD04C65F048D76086EA1156F07A47CA0FE349 -391E906747C833320E84E18781C61DEA8FACB8D9DDF08D29E5983F2E1FDC8C72 -C200B63415529A45978010EA5C150BA9D70CF4F5799DA551A1CF7041A17DD5F4 -153A868BD4B81A25551784E2A6EE42996F4D6CFAED97725C940C0FE9FFE0AA31 -FB2A32941E6C555FCF33B4B8E802C40B423599C8E88C6DF1AEEC28938FCF3BAB -B6846C20D7EC7278A909073BD15BA75F470F82237BBFF6E7287A3771378A944C -8CA6215F95437DCC9EA67F7A8721FA63614CA7BC5054EF5E5716FD4B7DEFDE48 -FA8D2AF9F0B3BD92BF5F48A0DCC8406B0A940FBB5D35B56A49B7D4605A00F82D -495AEBF2B413F19FE37AECED8060D5C32E9FE0EE9C0FB14045AE87D04B92A734 -0A35DBFFE12CB1ED64C924E4ADEE0AD635BFC70CCEC92FB07B1DE13E3D14B09C -94590CE5F2F4B7D0C697F6F30E217ED09B35917714712B1182D687302770C205 -C3D17944AC1CC6AE2A023707E13DC1299256DB1211650F76A969D74F940CA580 -6B499C40B76BA77D12688A8CF75E90A19AA3E368D6C99FCF8163450CAD6EA028 -84D4E9A5279013354D9C8D7FB8BCF3FD31433C822F0A412A3115B0E5E71079F6 -60C6BBE10380872D5D75F1BE9BB6DE755103E4B376458B97E0B50BF8932940AE -F95D4002737966FF15A0B67C5B717AFF0E95B9F8F3498D7CCB538FF133A977EF -3471FCE3B83D5395F282D1982B2A6CDBD1C0DE44B3CA286E7E3F3E82B3561635 -6E462A4ABFAE8DE9331FEABA97AE7E7C93F0A30F4E3FDF4DFD66E5CBE234ADD8 -0AEFB354B80ADBDC128EAE328AF10FFDEF587B462A88F62F463D640C4F8898D4 -1AAECA8EAE36639F6CC17B68BC1F1202F462BF7CB20CBD42FF2DEC420B4A7001 -90A1F1499D49731DBC0C5DD4AADC4C32A7349219F25150117D733A0D51A7E51D -88712AF2AC91D73A906CCFFAEA98C68DB967D96DA69E38A0406F2DD149B3E771 -68D65EF65F99A4AD33BB5B15672E57433BC84C9023BA77997E82473C557D18A9 -60F7064934EDDA12E614186A092930690D2DF97E1955FA75CA3CA077EC39A561 -27FC8DCBF13DC183774AF61C2B1B65E5E4 +8BF32C1F1BE935F51A1E6A2B3EEC69C02A0BA8F2CB4A4F68FB7896DC43147822 +7617A156AA00BAB69F17AB7D05874335CE3C819E21DB0FEACF1E752980A202CA +BB393069D59FAAEA4B47BCC0FB9C4DAF2FA0710A8A3DF10E3300A162A988FD1B +D02BB074BC5A4AEB6F0F3F89B3D68E9392AE07E73D7B8D18FE83564C52823804 +979B6136D35154A701E9448881565857394B0D7405004459EE0C68EC17802041 +03FCE184AEDD76833090A32DAC65B34FB1BCDC136D12DA0D6F734F09A5F87BB2 +5407964AD8FBCA56F0CDF8AF907AD5352E4D93A6386BB2006E0FAF74AA8D548D +FFFC997F92F929B794A07CA8848DB5EBA8BA904DBE1AE6DB74FD125E11D39FD2 +293ED39ED1780FDB87D969679CD590297FD9939ACC30B4728227077FD6353E98 +9E62CB8E355522861928A6A4C4747D5794F4DAE08C94FF902D83E5C9FD260800 +FAF713E15B90131C1230A572514B78C4140A3BBE1C1A394F4C0FC8216C9A44B6 +56C67513A4D15B6FC3997D906F69BD022A380D1E6DEAC37434EEC14CB066C7A5 +3EDB6E01DEDF4D58FDAB5A263115D8DD8467F551283B349D0EDCD102A4CDC4DB +6133E4F3942264E0BC3D4FA9F42C3EA90B4FBC54DA6CF0339D0EB1B1BED4D7AB +86DFC6133D38627E2BF545E123B6B848938B4987D5C793EB031AAC98482B242A +B4F9662932E171F439CC1F75B38084F9460FAEFDBA8FAEC336348010BE72BF3C +B481A0F628CA6A15602A648DEFA045F796473FA9D1D1838128BE6AC22EE49445 +14C049A7DDF8CE32418992973BE5A03C61CB64088DD227CE312A802C34FDB144 +A48C3F4A2758D0A547693067D9FA6A36FF3F6349791133C440B1A9D3CCEC40FD +0449009528C4DA20FDB85B57F30B9941D61BD6C722E4E42C243BD21AB59CF8B2 +461F44EC175031BFC898F198D9453F580363DF0C4CC10245A23FEF9FBB5E7AE4 +7EDD08A647BDF27390BE255F3C5E9590CC56B68BF26F97463162A601F6FBDB73 +6B9C7E6B0C9944C91F24FB36F87C737E4A30F3782AA2237EDD48A259D283515C +030E4FD0F67BC97E1C2E1F82761D4AC4E0F19D5BCE52F69C4698376EFADA56E5 +A7540CCABDCD035DD158BF6EEB97E4E491AEFA346B5849E8841E1C512926219E +3D3F1C444D1CEFB2468DB2AA00708A6CACFCEAA65D922EDC5D64A9A66B17C938 +BC7CA14D2EC98A72C976F149DFA98DE557C4A52700856693C7AB5D80151B1C95 +663D913F0AE40F67F2648524E6B06B379D9E0E2EB8E4CCE6B026E7AB5C3DBB48 +B3F6963F58A66C267252AFF7CF2391D350A43377DF8C3E08E6E8DB5E0D26C996 +441A716B3DD2778E2067A37E6F1A9887855A539CC282609A42BE27F6F815B064 +A27B8CE2EF121386E670AA7442B14BE8B66530094EAA93E3FC6668A567F760D7 +D060D8605CDAC6440F2CD8F24493BAC8104211B03A4A115E78DEF16372A1EEA8 +840A5AD4E050CE415A938D1D9E9F0286A8E6345BF7EC8D096833B2BFC9E94C08 +D2927028B30C62D9F95E9FC78FE7D598799CF3D0D24912899DF0A387FA5EADD9 +F3D617D218F949AC82BDAA67D3D2863C5B7311E63CB1FA6C633254477A570DAA +E98E2E08BDC5F85AF690C3E71D958F9F63373D9D8AC9A52B4B89F3DB04B87131 +E3123D7D06FF0B20365F0FF541AB3440579A0F482E74ED7331CE040BF5ADA33E +5ACE0D28130EDF1683C60D79B25103C71AE56B87006BA19C8EC3CE08EFF66FDD +C6B4551ED82322C9089FF612381C320B3792B66B952062FA2971ED005A468FA9 +F9CA87E42DD3F8D610E10824986E9A83961009759E216532ED5BB5A8C27EACDD +A83660DEA812ACDB82271E1BF1B15D020FF800C8E80D0DB2A7793D85F124E4FC +C89268A6159F1734E97AE92022955D040362EDFC1A2F77954B35840B42996675 +00F6A0C6283059263244190DF799E158893572F2650A0A27AE03BBE64ECCE095 +BDCC8924567A84E89A7AE812ABBB82A4D0526054BDBD6A44C4A86DCDFC76397D +B49C98C5ACA66CB80CF32455348D9968E19898677D6AC6C22FAE5747D8C6D9ED +424A9D671130BA557F0BE38972CA0B6F7439F630FB07C409CAA8302212C426D1 +77859925DFF96F842FED263912E6AEC336B99FCDCAB61E8E3BC0C6D7F760FB74 +051321626865771FF83BB6DFE1A9035BB3ACD54836B901CEC6F3AF5B6603E31B +864BEB1C6DE0AD60BDB42508105EBA426E0396B19EE14B539BCE68853929A63D +8B27167E4D43F5502AF30B8111E42A0A593A0AA52F3EE42C23486B16BE004F8D +93BDA3EFB798A58D10F79E8EBAD6DCA69D8CA91C1D6ED75036066D153C6057CD +CCCCF40784B26F87F27345FBCF45435223490BCF6B84B4CFC5AB7B8B9FDC5F60 +EF9A3F0B60A6560C57E71BE1557C5466EFBE1AD76CD5D59681C6164FEBAD21D5 +D93E01DD9A881648CFD245E8F0791B361D64B0DD8BA93BC783B4F1403E002676 +9A4DB0B69E646F4D4497EC87CA672056CA7BF0B5AA0BB7CBC8A93919A1224757 +1DF0AFABB5F2013DD3FD67132BCD5D30247C329BB6B13BFC3E683DCC35026FC3 +515DD8A2D629818A9A9C9AD3263D781B86F52F352A3A0FD0A4F74E5BA65FE64B +162BBE0E843C31BDFE4AEBE3782F85C423DFF302D4F4BB3FAC7C6FAE7870626D +4C118C4885ACD643DFFD9DD232309AFE871E57CE81EE352EBD82A9769542E5BC +E3AE55CEFC790B1744D6B09535CB1A17AFEA289295A88F08A607F28E2D6D229F +6FBAB27397A3A3266B3FC952538A01E066EB51AB2AF4C13790BDF92977C3D4FD +8C76653BEBFB42BF5A93AB343CF71E006CCB1AA6DF07C3BE55DE82D86552ED2B +63A25D1B3D892EA7BFBA8401BE87F7D3C0F70BA06D0806D418DE025AD2A44BE9 +B0576406EF122471F4080B32FC8397C12BC550BBEFE63B119210CCF2856BDA5D +881DE21D34C7BF597ECBAF72DE16E2443932C864AFCDF2FB4C233D510176AF0E +E6B9C20EE11CE7A78BA76F19F2C81BD3F5ADE5A47C74D77B6E1BA858132FA09E +44D167069ECF433A3F5B74AAAC73E1E95EF7D983ED370B4C2287FE814154FF33 +6788130449F5536E305865CF8C513E9351A5103A3F338082E4F1D5F0C3D4F5B4 +E20EAC7BE2F363B012FFD806C5D2EE99F48B92B41019E794C7BF7A410776234F +26459D88A4D68494BC281E57C8C2CDD5DCBDF64E9E4B184AEB5C94D09305C0A8 +72835A6F6DF44F2A7B1848CE38EC6E938E0185988F39B9BC62D4BA3071E7FE54 +6DC79B49BF6A42756F398ADD8156F322CAE4AB583A9E47A1453F8410AFDD420E +5D32F0408E7BA999F52FAEA73DEB5035F083472D1C4EC6FDFC6E029534749597 +6037B0C4D49484DC804B14C87D708242AD05536AB037BCBDADBDDA4226E85F98 +A5BB63E8885348722C0938FB9EE57CA792B20F06280969D8C231AB8090BFD160 +0991D1DF5F89432045D3A0CC4E361A2AC466A402F89F09D7238900FD50AD0DE0 +46D8749949662F5FFA5A2258E5D35F4818E107EF5010A9720B63BA107387EE37 +A4448F122BD880D288CD50DD5033D06A2983F7F62D5A93CC12F9CCAB25654688 +50C5E7091FEBF634A1C2E5DA4C8CAEF51F9D9BFE236DA6958759B19CDD522947 +C4E74F63EF468B19ADCFFF7E6D44EC6406C4F70D11575793D9B783B24528C867 +2A4629BFCB1DDB087888C5625B4B552851BE71E5642FF42399B0A362ECBF34EA +EC45113E3A978EA6C403162C496B3BE73E5C67B9D0F8559B189ABEED9EE5B5BB +BA5D9F8EEC40035F176D7E445743979CB013ED191F3C1D4D7ACCD8BF0F2BD9EE +C34DEEC3F2A88547A7E7910C9586AFE4FD55E41422CD70AD0A55C27A2DBF267C +60FCD61946C94894CEADC4289799910A0E8FEFB941E9492610B6006E19748779 +5D3D455A46A6633EF137D10AE2797B14F9624CE9380ACBDB482F729EC8171913 +C24781311366642B79643C88AFC58457B8753B2842F16DEF21FC2FF03F0184CB +83DB0E89B74A13EC0DCFB29D435286FFD9B0B5BDF3B844E02EDDA76D3E0BD977 +A86F8F2BB836545B3D7D8793D5D327D32E5FF48FCCB7686104A851501D74955B +2C1CEFEF59B031487C246BDD6DB2299645286233B0885CCB51F1E600E6C90151 +CC1DABEBB50A7BE6F66B06D6340EE795C53CA2238E90281A26D09BF60E8FCBFE +A3A37C91DE4974908657F5805B1B1567294C155DA7FAE5E434A371BD9592A4D2 +CF57508CC3EDFBC11EB406E668B8F1204282E2A9EA9173D983A6CC7F2D3F578A +3904E5EB22C286B7930E5519F6A40A23DA7A3088E274284C1F640D2773D1028B +D299D969145FCC9B5F89DF1D5BE6F847F9F49326CBA4835EF03D1819045FAE5C +72895A3D0828BAC414291F042334B17EE49D849928E39BD9A464D31346BA4D6E +03DA880AA0C3C78F283ED687E2F70DC889A7B9D777845F1097F520704CE81333 +9B6EA93DF1A11ED41F821A831C0BEB917FABC8F68AF945E95B0BC9B883724BE2 +BCC7CF84650B0D5B43FCA10052093E832AB862B354EE89129CDE68C7364BFF6E +3B93F0CA5D19228F1F44E015B4B8E8DABE4229560E89589F11BB46E0F42BC64C +273CD536BAF00DF26FEEBF9EC4300DF01B221FAE541132674E6D16F43AB98040 +4CB4D0A72F272FC3320DB8B4B9BA8161B4895FF9EE2B18EC90FE9C5FD3F40622 +8E510CF33BF664475ECD70380164A55ABB43734650170D44B9B9BEF6FC727984 +975D5053360ECC7C0A375215AD4AB63DBB7B2E3F75AB136F6BC002D029A9AAE5 +05671CD18D26006CD662C47A4DA9E7FA08CD9C9EEA9ECD2B31FC65D7071F0B76 +BA692C320C49910F61B1152D71A36AD4B10D3C80AE250F50156ACDB218F59CA5 +028E43917181FBE4B062AD0CB441A0DB976C2F7D09C30D37B09C55C4F5C420E1 +887B196B4468A42AAFBB95F69C79EC97B378148A3DB04011C7F33D9662C89D6E +ACD69C757851AA44F830EFB11C1D259C041E9B56924F84CCEBBCE6AA0D10E45C +73E191726704188DC82FBA0AD70B98C7B183C9C529B145C2DD63E08393185543 +1894E2588815FA14DCE9EF5BABD58AD3D798F64F9418B62B2E02686F8B8D962A +CB20B6B04E581B9DF6C52F544BE97CDCD2F2740A92226D97211DD8168AC3D13C +17360807EE886289C78768D1116E3EBD682120FB6F90278CB3A70503A8B8CD28 +4E0F7E5A3BD6B7CF63B5B6ED9431D8E1434587EB4B74EA388FA301896F3E0FF5 +2CAC688D84B0B33C87AB1A7DF3D90792E9B7442AC5B1A450230A9DC514D3ABC4 +C6A7EFAC0B18488844946BDE5DDC18FCD3D832C1D6C62633D6E46F3D561D40EA +2A3B225E71717A2FF5E6DFB29FB611FA3122FC60364104458D9CFA6F5BC74117 +5582AFD3A15115290BD8F966176DE34A62173844D79EC73FE81EE77448AF1A35 +5F4AA813530949CFD5E53F5CED0323292DA6B28EC13C2B35A3B74165A2CE729F +F9C7EB1A728077725790A4F0FDA6AC9D9942D52CCD8652959E0BA58EFA5BE6CB +B07DCC2FD207F400F01F7D910ACB7CB87ED3FAC751A8DAF3516EA71AFF38EB27 +705217106FD0FCA158063E80FCF454444A5C16DC12FFD5EBCDF0F70C1E5CCBE2 +ED0A6270E1BA271989BCBAACF6085AD252AD2137644450360934D03D6A014150 +FD21949EB35C0F2104DC44643C56AD864CDD802D6BA57EDC7F8263A86DCFB0EA +439875AF0EFBAA5CA147B7CF6DBC691E32ECB2432328FD3B0C7AC5E3058FF419 +2F629075692FBAA974E2071E798EE81CE61545D6BCE7B40DF72416DD3161CCA8 +EE3F294DD3C7C61CCDF78F69C1AB0B63F4EEDBC01372D240268F2C60AA62E8DF +EE52909ADCC47044BA3BEE85D077986F179CDFF53AD8F9F22B1897C7C5D23B5B +A8C26584116FEC0E562E688EE078FC2D0082F92090A8585A8178102D22BED49C +62C9F7B589F105541DCDD6A157AB685699C580C282A5BA26126FB08FEEEB9CD7 +71781251823AFEB12F5B37DB4CFE59D5B23281D33911416D8EB55CF4DA0CCC88 +E380CB53BAFF81CEC5F29FB54DA3B66231E0A24BE4EA672A08F9E2046AEECF4C +B9AE458E76A3FDBB1A1BB37BA2F8E756D5E3D96A97750B0974D67EBAC26D6C17 +823A144AB04D93D93ABD0FA46E52D4FA04504542C6FB9ED028297D9B22F6C1BA +2FD3773F1E71E4BA936A4033351E12F48CACA9137BBA250D145D5A3E4B9BCF81 +F3EFFCD532FF2DD2085AA5F8259393B316EE9C9E3DC74C2B0015B018D1DDA120 +BACBEDA6E0BF7D91DD13E0D6AE3000E03E9FC0A2871C909476D2FA8B1E852E68 +2A20EF414950FE7D899F554245FB6E041723FFF36FBB0CDA14BC162C81884487 +A255D99BBA35BCBFED3369730FC89EFF68B64C5E84B007230368B32A7B2C3476 +6C1CC1F41A951D9D84B796EDFF484106F7479ACE356EB889453E138A98DE20F0 +F10EA068AF4B2C67F877AF2FC067669891F7EFE3EC3AD48A61CCB907C6573868 +0A47DD38ED7A60BFE77ECF4E6DF3DFA70E5217EDBF20DFC9F5B707665AD365E8 +F225B0708F9877CA0D27F6BF42250854129AB0F0096B03E653C83D65B03C4E4C +4B5B2B2FA881E58D94813A0C82B4BE017D7FE636544E7E698ED1F229372E856E +5A9D61BA773D85DB651D44FE34B770D37D6AA24B011C27A421E12FE0DAEEBDC7 +4EB72CCBDF1C68968DDA127416C7508FB39F3CC98DA18D3B00D083BBB9092413 +05582D08F7AEE5866B030F3000E08C4B18C3798B64511EC0B8C5F64625445609 +EB750668DCFC76A6CE41F18808D4D59CD8C4DCFEAE74E4AE9B5526774484C928 +3EDD497B94E12A6B8AA151BA9071A8A6F6B842C568C2FB1B9DA2668928966A71 +1FF06469F4EC05524A59683E4FF003D0C1D8501B35172985D3AE7B0104915E3C +1CDA23EFEA6702D67A2FE1C37EAB2AFEA5B23FFC3146C0AD143FD4B67E240A12 +A9FA5BB54B85B8B0DF788A9B6D70375D293BE862A648BA03620BE3D00F5DB2FC +2A5CB1CDDAC650FE19E4E67BE94F6D2C0CA491CF04736F001E8A440558D7630F +18B6F0C51A7A88D7DDF3B3E0B356CEDDA2DD90F1DEBBC2E0A00D356240D95D3D +8804DDB50C087DD7D743D37F787D519FF0E5331E40FEC71FC172B7B9FB4BFBDD +A9E4ADBDC72B68AE0B906EE04566DE98C2142137787C6FDC6959BCFD5DAFED7E +745ED34DF81F2BE2BA71FD29ABD9F9EA2EE83188B3530D0BF75A8524CB3B74B4 +8894B558118BF20CDF56AF809295491269D2103B8EB87B7B1E9FDC515E1BB263 +7BC9148A7EBFCE70188D0B1A17B7D658DA1C68718B5D877E766ADB4F9E1D2CAD +09F2D2A0BEC2AAAF29E2CE02D92AD9D69EA3B82725A81B66E6D7DFABEA83686B +43DDE5495E14ECDFF314283FEE34E12304720E21AD065ED65CC4927B2CF19F19 +7BFADECEB4AD2A72C922F275841A9A32B7F59F9CEC85993119EA5D84960A7E16 +A78AAC396EF0E30C9EA0F14FCFCF334B2784901240F83DA2D65116EAFC92AB25 +AC4E2BC6A2C67258CA0D0C97E5EDAF526293704A8F30231A677CAEA7CC36B6A5 +8BBE2CB635D030C8C189600BEB6F248862505AADFA5987F9B2FFD9E65C475FD4 +66181794F9F982943E3AE3FDFFF95E718499732568399B5E09D8D5C7452212BD +53421EBCBBDA4E61B97C6C85202EEF7891A2622566D4896702D004BF66CE8D79 +2EE381738D33D21B9EBC0B38CFBA58BAEC3A5195FFAFEFD39494FC304B540FE1 +079613FAC7D7CC0C1785640104E8A3AB50AE83168FCA02B4B26315EBAA7BC21B +CC30F1CE54F9947B32AADDBF8BC40A820A69B1508EC0C5E58E6453F95734094E +47089BC8E7491769E9C2D90AC2A35D9F4ADC88108863684DB8BDEEEF54BF923B +02AE114B153494AAD20A984AF198941C64A5A7DD2EC3EB037FA8BADACFC42754 +017BDCFD966710A88D82A1E9351543573607CCFCCCC3FFB85C40AF2F8EA5DD8F +C5261348F689AC3936833AA9F3A61C344444DBBD6635F920320D4E8A4A5DF1B6 +CD5FC3695819DE927A2974102499CC0145FFA6C52CB1F2B93C3C83249C780C94 +BD8D968A41F35B333DE07CDB261D0ACD1B2C95A2C87911B6C31C14196010ACC1 +CD88179FC58B95DBA799A38CB22DE08C4BE0B3FF4BC6B7BFC4E36F70C5E28C4D +791A6CFF8D40B32829C2D7083E25FCE1F58969353DDFF9FDB9290C530FC5E907 +2543ADEFC8D6675476C8ECE2D56E79F51FE9E0C5581D6F2AA7BB8AAE16563092 +7232722A00D49142B0421EFC1B648980ACFA873656615001E39EADB5C2BE4668 +66BDEF21952587EDF9C2B0087924EB9E312D59A1C918833AFE94ECEF30C2AEAB +AC5A38B2537D033F9B400FEAFC3DB5BD5DED92A10E74FA6BC97ED38E3F7F0755 +3C4319A7CCB2338580EF7E944FC98C621C049ED5E53CA6750E57AA903C05E3D1 +D5B5E1512D1AA6D7572192D6A395EB192A52499749858256BBDA1CE13DAB0E8C +67DE9632B8A19DE09A899596614DC6C509F1C851681DE8F1ABB93BC53B04DB7A +1E3120E0A2035141A410F18CD592CAF1C03EB8A6E642A560606B5CED064496C3 +055A97E4FB2211478ADE9DD8A53CC505B7ADD6411B343B0B09FF0F83B5BAA230 +39BEAEC22943DA553BA26E6DAFB61BB3377A2B3204A47097A5C3AD274C13436E +4C4E602F6899162FB5546E16C8D1FB5DF0AAB4178A95666BFA72BE46624C859A +ED91BA5035232461F7E513CA17C4E888097A00C9393A24E35B0B527E152ABF5A +D8791D481D237DDBBA411729DE4DC1A0466DC8F226569D941E88AD50722B32B0 +A368691B04E91C480F7DADD1D98739136FF55E3EA6284EE4A6481AD1E4C05362 +4550DBD19CC0D3443B88461EB9D686BD4E06E4E95585F88B54B7A49C60100EDC +39DEEC2C7C89668A546C3D3824C1A2E93A621D4E6ED4DD5D47151E240D00E30E +77CD08B5A15EF03311FAD97D4748CA80E03FB945B750E2A371EC67FF8ED0DA4B +45295D022E604D6BA9C9A2F82588375177D470D6D1221118DC147FFB77815771 +52C863DABA9F323FD85F0FA14E50AF8432AC0E490290F944A92951614606049C +C9EAF7132B9B96E79EB210A1EA3FE119F0417F99A69B319394357CED4ACB1CC5 +4D3FD5A27036E1AF8FBE81745BC66952F9B8327A80AFEDF31284CDA472A5D541 +5B0CCF34A0E0552037C297482C0424B08D4A865A3857E842B11E2CDF5D95955B +6603751890D83E8A9E37A04BE5C63C2DB06D6CDEBB6814E3BBCF77AC7BE65C84 +D6C0BC053FAEE8D3903D344FD6CC6929DE351B1382D334CE8FEDE5F0C489C948 +3123BE9C7385219A39B31BBF6E3D11BDE47FA99D56DD91D667613C87349DC66D +3687676D7CAFC723B694C106BB4D27FEB329B751A0EECB8A816D816010C073DA +F5BD48098375827561B1B7A9CD8A1BF6AD13CE823CE3CEAAE35C0B5F70CFBA7E +78922CDCF4BEDC0EE6C19260E9FF82310CAF25C609C811C685BEA557EC451E3F +65244B6424D6EF39A76758F934FB02C77FA4FA37F06D91B20711749962867B3B +5564EF4221E66F66D77ECA275F3E8BF7976DC2D0C1EA8CECFD50CCD12E183126 +A9418AD9D601865A5D168E2298E6B99F9C8C789477CCC8D607F0C3B86263BCFF +A42723F7F98152D8AB8BBBEDBAD28939A5F411D4B36ECF5068569B365F72A205 +8F763D8F968B1460A46344F77218A93FD44FFF5C747E9688E9DA572619CF0A9E +62E76C7EEC4A65349874F264B09A9E440F2F378F370E0337007C31F1DDCD5A8C +7D6BCDCC0734D316ED13ADCDDF39BF2DFBD6991C5B98027313DB8AEF1F3D5413 +D780EE5A3720B962FFA586966E75E4F064BF6F377CD1EC36A3D214D4F937F7BF +5D468B82993260D67878443F6D62F0E66BA31662DC26B77A9BFD958581C12158 +3D4490543A8EF43024BDD308DC03758DB8AFA6BD3735031D6543A93B03C07615 +7254F6E3985322D236C254B2170A5F058B27805DDDEDF15F322B6B83353BEEB6 +3953CC1EF2AD8BB529A0354CD6C6BC8DA275B2B5910AC60EDDAD63AFAB60B91E +FEF7CF4E1DE505F151DC34B361C8B28BE592C85F70CEC2A5D2E1212A185AFE8D +17E050A3386D95622ADA81CF1B49F441C45F6D3BAD328CA8B44FF892DFDA6BC0 +AF955998156294AFBF076489E21B33548DA4D48296545AB76C8EDF5A3CC623FF +022BE68E289615E6BFE4762B512E859F6C675AA6AB15C6EA447680BEA8623A17 +A7B75EBC69D9FF42B1441D61E57B563F152458E0224D1C0A05281A34BBE60B50 +2538A62D83DC2A5C3861330C2E9F6F645986B0429FE32D6BE27CCCFEC7AFC0E3 +E88634FB1B8E1043B4161D511AEFA2529EA0A334901D424518FEC1091501D35B +2C01F98DD44DBE964D669F975646D70F8871C6C6E357C4A368F32EEFFCA56B5D +95D40BF5E52A6FBEA4D1520DAB2241BBBBD19A517EDA5F2C5773D822CD8B8BF5 +36C1C62F3E23AF4AE255AB0AB66513984AB9F37F28EA9E11DAB0C59526637909 +BA89D0EDD0A3E62CF280D02F5A4FC8BD063E33669C4EC6F5FFE998CE424AB8CD +2224A23F41B3A2FF975C5C3CD8A2E179436BB62D5C228C7D02129621FB630A2E +477D64BD2360F28C1DDCFD43CD261008E5EE14AB3AE73387D76E0E7FBB49AE1C +3892FE09A397C35740E6E2EF2B783EB0CD2A2A8F01642CF988C8C2F01D3CB208 +368A37F2CD356AE129E4BD1DA5B4224DB4C2A3F6EF43ABD3127F119CE59AAA50 +7F3FFDE5EE4DA7B5DB7E2237C9C612E88F65D6AF84E91E3DA6044A6E4E685F4C +9B657AF9488E8F07DE024B6A2A111E33CD869D4EA16212970DD7B14502858F7B +4906040A2447BDA84B192D46B4B340DAAA674B9DA36A8301158C9745CA11A95D +3EA301E6BE26B103EAC473509DBD45A3405AF556DA77CC42E1A8F1C88C71B038 +E78FF38FD862615B27625561B4410FF6B00088E296F430A8A57C54D0C8E35C14 +561FC0471EFFD7D910D63F173BABD8984CB24B501E18548C54E89D7FDB9DFC65 +59B355C6AB5D412F8F91A82386CBA9AE283BC49058462580863A753C45C75C94 +1D889DAB030888A3A70167CCD945D35F396391724FA5B1637EE1CC8C24D53B93 +B95EBB6372F30CCF5A54305030936AC183BE80E5BB18995D6F1A1D9756C995AA +BA4272B4AB2F4D29A51F696FC75BBF78FA5524FFD2257701BE792D3D531515E3 +6801ADD6EF27D117C713AD79C7D9E6DC9BE752D2B731187834177BAD1E5F2710 +ABCF2A3FF1DE206119779C50BCAB175C0316D5FCF0156C344C10A7BF825A4470 +0E9B34EA7A0EBA52138D61D7FB0449B5E281929542138D2698E2C88AF1E0E247 +96FEBAF1172142B8103D3E28BE5CD34E0AE26F915A347E4F6ED3474EDE940522 +D58B3354246A05485B51DC53AAA7FF1EB279C1101402A240EB38621A8B8844EE +62D7FDF10E63353A904A834BD3CF1C84C235C42D636BF73A2832063B815E13EC +72EF0EC7EB877AE7A911CD28638F55186047AD33A536F54A8129AF42B8489D88 +EFB733B34695764CBF01E4C59C577687CD3F8A5F6A69397235EC71A85B30C5A0 +6D7B9E31DA11AC45D5FB9E133E124C95A7910C3D66CCDAE747EC6013F4D22DCC +A381E3EB9F359CE8644B13ABDC73F2CB6CD44F07F711F2E64861F948140EC6BB +4CF29D5532F62CDC98490A2A8F85A87F57E10F64E47C817E9FEFB2668C2D0010 +DF16161E7A8475F6BCA788A07A9EBC81B811A24A485FB532E382579329CCD64E +2C1FBBFB65E58223F1E33A18C4FCDE84B0C60A0B3F6F2E150570DA33EEE3FAEE +35DF52573E487223A23705176F5818C1E30F199EE005DBD1B0206F9CCF26C3F2 +C219BD50EC2E351D915096EA7B505CD5B7D3123C3E82F00E3313DA1D6128897E +5B2EAF7B8A48F75FB143E4E5AC63CE4740F30A0A8EC555986CF2A93016F4EF3E +C40DAF655E9CC9168F5A9A13729DB8F2FFF4086BC2FBFFE3E15F4077DBD07A3D +6337D47B8CFDCF2B2DC2E63A04C8E7E7DC9416DBE7081C27BFB67D33BA154B97 +8DAFD7F12C3F3E04F52B87B340B6EC8BFC2DFE2D176EAAF507C109FFB78C18DA +6703BB0301C804535E20734ACA8C1F5CB43A5648115175B63DDC626CEA6B4F52 +50BB6B0BD14ED98CA678B1451E549B73BDFC7256B5311909AA4744540E2F4AC4 +D6C42C010D47E5A526D39CD5FB80396954B7217B553E9843D525FFFBBDC9A2E2 +B39A877EA50449365A36A8C8D4D8EBDCFBE617C941AA71D8CC5B09E36734B014 +9645CAD85987BA89803C4ED19FCAD46000C9847D5618606574B41BF9EB9E64A6 +A2C313A9C25F72CBB1070E25DC10AA059A0910ADE3FB78AC91EFA287D4C77975 +1015B7F264C4496EBE54CAAE1A859E63B37006DDB51BB03641C0693CB91181D5 +0786709EB0A3C8EBFB1A6D2E0BA2C804B3A790B22E6C2C5C4CFA96BBB1C6BD4F +6BD98B17CE59D6506FCDF158B7E06283BE21E94041F97A14979358FA8D043AAE +6C61F6757F066EAA1DC9971307AAFD7D67F7B93F32F1AE6CD11E48A786BAC474 +B9465F52711DC08721FEEEFCF725CA4918A83922058BF7CAB2BF5720D2EFFAFC +0D7743CEE05135C1A172B74150B0A256A32BCA3F654B294DF0B29F777752EDE4 +A2F18B4D92F7CF38525E298E04299849CC535F405A61A20C5C50A1968B753CAE +07335CBD535D3C72449157ABCE83F8522EDA7236C089498F8C44C9D850775E97 +FD43E40726AA6AEADDE4379C38350D54893D238974FA31BD65DCC411F3E4F01C +AF47ADA23F44DEB5EE1D90B0129E35F6A141738B8E939DE99AAC5D94BE68802F +902BFD4FDA6EDDA70F1D4E979D9BA77E4427CEA58E42D87899DED7F3D5679E71 +F88C0366AAF9ED39D296132BC2891E97923C9FB8852E2F56914E1AB24F2A07FA +64C4CFA4B3207DD4990C1290379D5DF541A491A05114927BA77B20CA345A6F5F +865D18190DE6D6EB079F7CC6F56B2A082D7847C00B521563BC5006F96EB83F6A +DE78AC3F7034C1D434DC620A7EA95AB2EBD9BB94BDDBF0B5722B2148E7B4811E +C8CCE48DC8109BB83C8FDF41DDAFDF450B55A9C310C179427DAD501FBC1FE7DD +0349E94582C22F915664DD9C4963EF1792C258A138DC83F96333789684BA1181 +D58995ABBC3515628AD5BBD3F2979AE30D9B13E290137E54F21AC5408C5DC3CA +CBE34EA9E903180D81E9DF0ADDAF6E77E9E554EC557CDF93A65B87F2B2FC8C8E +EB7D90081F0218E41A869E2D5B2B0392D2F0FE721F050DC8683D75DE82E94C8C +1EFFD4CAB2698F65741E7BB37DD54D5599016B5C7D42950520C7ABC612442216 +9E90D84D0327D21D47C4EB5D10278ABF5D52C94021181299605576BD4EC39F58 +095B1062DA895DC8DF983862CD1CB24D8472970CB49BB77908CEB0C512A6AE51 +7A3F69A07DAC220975F73FBE94F82E29A672D5CF65C84AED4554650F815571CA +3A98619E103B215968EEDB12819AE6BC3F6BD6073F4C33931A9AA0D81134410F +46C6E5CDDEFFBB1BED5B924FE58502FE97DCC973C8BAA80F42546E3780436370 +637457C82494804B89E859164F404B67705C7D5E7EE5C8B72D454D85144C1BA5 +9B73B73014DD989761F1AB5015273B4EA9F7FFF87ADDD9929F8A5705F49BA3B9 +67BB0F491AB22AAFD699DD53093DA73FB1D2292059A31DA303D91C0AE99B4DF8 +20A669A9C8B307C723B4FF305CA08DAE05BCEEAB0EBAC5EAA2941AE37B5C1C6D +B906EFE67349DD3C808F1A58E468C47D7F9467D5B163E7807FD8934389307CFA +CD72F3C028F458658E0EBF3212CEF2DC57CC1569090E808F544A1F8C01268F9F +6CE1305CCA58376661553807CE98BD64180791B6053E5F5B8DB33CCE3A5474D6 +99A6269656E260E9E3CA51E549A5123C90FCAFB01DC0004322A149D1910027A1 +59E71BDFBF8DC2FCDF730747F89F1624BF608CEB937107AE0C0D4B92B13D1BE9 +7C77EC964D69EEEC02EE6EC06EF646B69A7269D49BAB698A8E7BAE9F61E875BB +1ED47150A53983FB314EFE6C345667701DFDBCC60566508C8264A929224E46ED +7D5091F7A563A97516E885F8702C9C693CBF361CE8503E86BBF983E826BB96EB +2AD5B07CDEE47E1F392D34CE14D44A167C3357FE6B7B760C63F78211F182854B +8D2BDFB4C910D6D36FF2415294AC84F7CC5DBAD89887CFF021B6C8DEC98271AE +386245779B38830FFDF6CFCC72F0271337E660BA96B6A9EED2CC85452DCE553B +21003D3890638C55EC3F372DCE3F78C8ADD68978656BF5D5ED1833EAC3156809 +3D779953B778336404BD7FBFDACD2B40169B30BF27F81ACE3F556B0E57232840 +9915285AD0A76E039E1B27A07536EEFA7554FB80E138D3E4288A554A775B98F4 +A3A97AE47F71FD60548FB927C3617D133F1AFCC01530EE36E284C5F60B319858 +9B79B63EDB1176DC1D3089661AFB824971F4EE6A7422C097A2A02C5B715D1D06 +F4AA09383337FD604D7EDB5060E70AF6BBE6F506FAA0EFCD79D3A4C12B4B3A20 +52152342C367691CDE79BA8CBA7C3EAC35AB75347A12C219BDFAAE94F5E51605 +D7D13A3EFD3F4526E705A3FABB1D1723FCB23FBDD72377BBF894FA19E9C6A52A +140AC6194B7DA07C4B99B67EE9A5AC5E179CDE082C086F1DC4D15A2B8CDA1CB0 +0A6D15FB974B17189BEFD09A4AA5D1B2D496318A739E7CCA40F711AF7D0A144D +F8AF19EAB4AC59AF5B3FF3315575869BE4E4846FF09D38CF28D4A72E9F64C3C8 +06BB5288EC2D86C5B1D775D2345476CADDB937BA6D510EEFF9E9A3BEF08872D0 +BE4AB08CCEEC207B26C215046D728E9D8F4332BF4CFFED2EA7685270AC0A65B8 +0005D013F1E7A5E180D595D5F0F622A8E25C6C65B0EB196B8B3194F49677AE27 +D3E64995EAA829AC57BB6378E2F0444E0CB4E3DBCCF25DAE6EAED6965FDDED94 +5384D050B567494E0E89F3F270F894CDD5E2231C4168D56A757F04D97FF4BB97 +FD46A8FE6ADB66047FEB3D034F1FEA4CE01653F31CA726ABE43109B01F143FE2 +CEDFDB6CC45FC0F63AE96C7D06FC3762F2BAE65942403D910F670ED2C1A34021 +E8461A5948DFEFC28F74BE4BABAB17BB515953CFE02C0DA932B7FF0449A8D99D +A6441306D001F676635E9251018F94556FE21A251F89882FF6ED05031786F1C7 +C056708BE36B512204106C2AF121A0FCD617A4410F9E2622C6DC6EF40FEA93A1 +875E53AC60C5B29A63DDEB693C3AA9DBBAB53A78D44F1896986D9ED77AE81819 +FC04C5E794FE678BCA5BD6F831AA362CB56CAE3FECFC661E5D8E672D8E6A9CF4 +337D177B73BBAFF89E0305B611952BA06488FC52782C1CE5C7CF2CD9ADC85888 +DC3F62DA0C90525E29935F3AD78B14A9D697EA0A4EAD9DF0D8B424D4D7EC3400 +0F1C4CE7BB586A75BF07A30729BE3C72E602C0628CAB7B1EE1C1EC928F7E2CDA +753BE0A5675C210C075654B58E9124E466B78A5935D6FC8C65C3417DB8504D00 +2255E63FE52069E2F15755764FF266D9F0C56D89743F2A8F349B1FFD8A91C5BE +F1F7933123CFAE944BDDFA98F4A8C702A12AF4777BCA487FF31060E8C58DC6B0 +4592DEF5D209518E88EF4783F0EF66E9DFD58D5AF8A56D7FFFF9BF611BA5EC33 +72A063A982793C163ECE15E824DE2D13E49C40529AAC183543DFBCAD1CEABCAB +CC31ED9C472D76616AF72705D42E7642F060EF3E4745CB3C8C6A75E8FBCFB7ED +18676984F53F4486CE489A4A66FB34D7437FF12B90B8A5EB7B04565FBD465DAD +E3CC75F67A7E774C96204A3E01E1F6DE238B90808B33B5F13ABD73EC4E594202 +768180D53CC11DFCC77B4C56BC06327F56991DD50777486BC4C2C3ADA85D2089 +DBFA423CE52A214E162FFD087244B16C9422A86B4508EB8FC692D507CB6C1625 +4B74A1617A2087327A369D894ACCA16797B210DA13C8C47B71E286C0FAC082FF + 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 @@ -2303,7 +2299,7 @@ 49.8132 /CMSY6 rf /Fb 134[32 1[43 32 34 24 24 24 1[34 30 34 50 18 32 1[18 34 30 19 27 34 27 34 30 13[34 44 1[41 47 1[54 3[22 1[47 39 2[43 1[45 6[18 4[30 1[30 30 -30 30 1[18 21 18 44[{ TeXf7b6d320Encoding ReEncodeFont }41 +1[30 1[18 21 18 44[{ TeXf7b6d320Encoding ReEncodeFont }40 49.8132 /CMR6 rf /Fc 135[33 3[24 29 4[40 58 18 2[22 36 2[33 36 33 33 36 50[22 46[{ TeX74afc74cEncoding ReEncodeFont }14 66.4176 /CMTI8 rf /Fd 134[43 43 59 43 45 32 32 34 1[45 @@ -2321,13 +2317,13 @@ 35 35 35 33[{ TeX09fbbfacEncoding ReEncodeFont }86 66.4176 /CMTT8 rf /Fh 134[60 60 2[64 45 45 47 1[64 57 64 95 32 60 1[32 1[57 1[53 64 51 64 56 10[87 88 80 64 86 2[86 -90 109 69 2[43 1[90 72 75 88 83 1[87 19[38 45[{ - TeXf7b6d320Encoding ReEncodeFont }36 99.6264 /CMBX10 +90 109 69 2[43 1[90 72 75 88 83 1[87 19[38 32 44[{ + TeXf7b6d320Encoding ReEncodeFont }37 99.6264 /CMBX10 rf /Fi 133[31 37 37 51 37 39 27 28 28 37 39 35 39 59 20 37 22 20 39 35 22 31 39 31 39 35 2[35 1[35 3[53 72 -53 53 51 39 52 1[48 55 53 65 44 55 1[25 53 55 46 48 54 -51 50 53 6[20 6[35 35 35 1[35 20 24 20 55 35 27 27 20 -2[35 59 35 20 19[39 39 41 11[{ TeXf7b6d320Encoding ReEncodeFont }70 +53 53 51 39 52 2[55 53 65 44 55 1[25 53 55 46 48 54 51 +50 53 6[20 6[35 35 35 1[35 20 24 20 55 35 27 27 20 2[35 +59 35 20 19[39 39 41 11[{ TeXf7b6d320Encoding ReEncodeFont }69 66.4176 /CMR8 rf /Fj 141[57 2[69 76 6[69 42 63 76 61 1[67 14[103 2[103 1[131 9[99 16[69 69 1[69 1[46 3[53 53 40[{ TeXf7b6d320Encoding ReEncodeFont }19 119.552 @@ -2342,148 +2338,144 @@ %%Page: 1 1 TeXDict begin @landscape 1 0 bop -169 -357 a Fj(Org-Mo)t(de)45 b(Reference)h(Card)g(\(1/2\))546 -242 y Fi(\(for)23 b(v)n(ersion)h -(3.21\))-150 -42 y Fh(Getting)37 b(Started)-150 125 y -Fi(Put)24 b(the)h(follo)n(wing)e(in)g(y)n(our)h Fg(~/.emacs)931 -102 y Ff(1)-150 199 y Fg(\(autoload)38 b('org-mode)g("org")e("Org)h -(mode")g(t\))-150 268 y(\(autoload)h('org-diary)g("org")f("Org)f(mode)h -(diary)f(entries"\))-150 338 y(\(autoload)i('org-agenda)g("org")f -("Agenda)g(from)g(Org)f(files")h(t\))-150 408 y(\(autoload)h -('org-store-link)h("org")e("Store)g(org)f(link")h(t\))-150 -478 y(\(autoload)h('orgtbl-mode)h("org")d("Orgtbl)i(minor)e(mode")h -(t\))-150 547 y(\(autoload)h('turn-on-orgtbl)h("org")e("Orgtbl)g(minor) -g(mode"\))-150 617 y(\(add-to-list)i('auto-mode-alist)h('\("\\\\.org$") -e(.)e(org-mode\)\))-150 699 y(\(define-key)i(global-map)h("\\C-cl")e -('org-store-link\))1504 676 y Ff(2)-150 782 y Fg(\(define-key)h -(global-map)h("\\C-ca")e('org-agenda\))1364 758 y Ff(2)-150 -879 y Fi(F)-6 b(or)23 b(the)i(man)n(y)f(customization)h(options)g(try) -68 b Fg(M-x)36 b(org-customize)-150 948 y Fi(T)-6 b(o)24 -b(read)g(the)g(on-line)g(do)r(cumen)n(tation)i(try)111 -b Fg(M-x)36 b(org-info)-150 1147 y Fh(Visibilit)m(y)h(Cycling)-150 -1297 y Fi(rotate)25 b(curren)n(t)f(subtree)g(b)r(et)n(w)n(een)i(states) -291 b Fg(TAB)-150 1367 y Fi(rotate)25 b(en)n(tire)f(bu\013er)g(b)r(et)n -(w)n(een)h(states)384 b Fg(S-TAB)-150 1436 y Fi(sho)n(w)24 -b(the)g(whole)g(\014le)854 b Fg(C-c)36 b(C-a)-150 1614 -y Fh(Motion)-150 1764 y Fi(next)25 b(heading)1043 b Fg(C-c)36 -b(C-n)-150 1834 y Fi(previous)24 b(heading)921 b Fg(C-c)36 -b(C-p)-150 1904 y Fi(next)25 b(heading,)f(same)g(lev)n(el)685 -b Fg(C-c)36 b(C-f)-150 1973 y Fi(previous)24 b(heading,)g(same)g(lev)n -(el)563 b Fg(C-c)36 b(C-b)-150 2043 y Fi(bac)n(kw)n(ard)25 +(3.22\))-150 -36 y Fh(Getting)37 b(Started)-150 96 y +Fg(\(add-to-list)i('auto-mode-alist)h('\("\\\\.org$")e(.)e +(org-mode\)\))-150 179 y(\(define-key)i(global-map)h("\\C-cl")e +('org-store-link\))1504 155 y Ff(2)-150 261 y Fg(\(define-key)h +(global-map)h("\\C-ca")e('org-agenda\))1364 237 y Ff(2)-150 +343 y Fg(\(define-key)h(global-map)h("\\C-ct")e('org-todo-list\))1469 +320 y Ff(2)-150 442 y Fi(F)-6 b(or)23 b(the)i(man)n(y)f(customization)h +(options)g(try)68 b Fg(M-x)36 b(org-customize)-150 511 +y Fi(T)-6 b(o)24 b(read)g(the)g(on-line)g(do)r(cumen)n(tation)i(try)111 +b Fg(M-x)36 b(org-info)-150 716 y Fh(Visibilit)m(y)h(Cycling)-150 +872 y Fi(rotate)25 b(curren)n(t)f(subtree)g(b)r(et)n(w)n(een)i(states) +291 b Fg(TAB)-150 942 y Fi(rotate)25 b(en)n(tire)f(bu\013er)g(b)r(et)n +(w)n(een)h(states)384 b Fg(S-TAB)-150 1011 y Fi(sho)n(w)24 +b(the)g(whole)g(\014le)854 b Fg(C-c)36 b(C-a)-150 1195 +y Fh(Motion)-150 1351 y Fi(next)25 b(heading)1043 b Fg(C-c)36 +b(C-n)-150 1421 y Fi(previous)24 b(heading)921 b Fg(C-c)36 +b(C-p)-150 1490 y Fi(next)25 b(heading,)f(same)g(lev)n(el)685 +b Fg(C-c)36 b(C-f)-150 1560 y Fi(previous)24 b(heading,)g(same)g(lev)n +(el)563 b Fg(C-c)36 b(C-b)-150 1630 y Fi(bac)n(kw)n(ard)25 b(to)f(higher)g(lev)n(el)f(heading)424 b Fg(C-c)36 b(C-u)-150 -2113 y Fi(jump)23 b(to)i(another)f(place)h(in)e(do)r(cumen)n(t)350 -b Fg(C-c)36 b(C-j)-150 2311 y Fh(Structure)g(Editing)-150 -2462 y Fi(insert)23 b(new)i(heading)f(at)g(same)g(lev)n(el)g(as)g -(curren)n(t)104 b Fg(M-RET)-150 2531 y Fi(insert)23 b(new)i(TODO)e(en)n -(try)700 b Fg(M-S-RET)-150 2628 y Fi(promote)24 b(curren)n(t)h(heading) -f(up)g(one)h(lev)n(el)285 b Fg(M-LEFT)-150 2698 y Fi(demote)25 +1700 y Fi(jump)23 b(to)i(another)f(place)h(in)e(do)r(cumen)n(t)350 +b Fg(C-c)36 b(C-j)-150 1905 y Fh(Structure)g(Editing)-150 +2060 y Fi(insert)23 b(new)i(heading)f(at)g(same)g(lev)n(el)g(as)g +(curren)n(t)104 b Fg(M-RET)-150 2130 y Fi(insert)23 b(new)i(TODO)e(en)n +(try)700 b Fg(M-S-RET)-150 2228 y Fi(promote)24 b(curren)n(t)h(heading) +f(up)g(one)h(lev)n(el)285 b Fg(M-LEFT)-150 2298 y Fi(demote)25 b(curren)n(t)f(heading)h(do)n(wn)f(one)g(lev)n(el)233 -b Fg(M-RIGHT)-150 2768 y Fi(promote)24 b(curren)n(t)h(subtree)f(up)g -(one)g(lev)n(el)301 b Fg(M-S-LEFT)-150 2838 y Fi(demote)25 +b Fg(M-RIGHT)-150 2368 y Fi(promote)24 b(curren)n(t)h(subtree)f(up)g +(one)g(lev)n(el)301 b Fg(M-S-LEFT)-150 2437 y Fi(demote)25 b(curren)n(t)f(subtree)h(do)n(wn)f(one)g(lev)n(el)248 -b Fg(M-S-RIGHT)-150 2935 y Fi(mo)n(v)n(e)24 b(subtree/list)h(item)e(up) -642 b Fg(M-S-UP)-150 3004 y Fi(mo)n(v)n(e)24 b(subtree/list)h(item)e -(do)n(wn)558 b Fg(M-S-DOWN)-150 3074 y Fi(kill)23 b(subtree)1097 -b Fg(C-c)36 b(C-x)g(C-w)-150 3144 y Fi(cop)n(y)25 b(subtree)1052 -b Fg(C-c)36 b(C-x)g(M-w)-150 3213 y Fi(y)n(ank)25 b(subtree)1046 -b Fg(C-c)36 b(C-x)g(C-y)-150 3310 y Fi(arc)n(hiv)n(e)24 -b(subtree)976 b Fg(C-c)36 b($)-150 3380 y Fi(T)-6 b(o)24 +b Fg(M-S-RIGHT)-150 2536 y Fi(mo)n(v)n(e)24 b(subtree/list)h(item)e(up) +642 b Fg(M-S-UP)-150 2605 y Fi(mo)n(v)n(e)24 b(subtree/list)h(item)e +(do)n(wn)558 b Fg(M-S-DOWN)-150 2675 y Fi(kill)23 b(subtree)1097 +b Fg(C-c)36 b(C-x)g(C-w)-150 2745 y Fi(cop)n(y)25 b(subtree)1052 +b Fg(C-c)36 b(C-x)g(M-w)-150 2815 y Fi(y)n(ank)25 b(subtree)1046 +b Fg(C-c)36 b(C-x)g(C-y)-150 2913 y Fi(arc)n(hiv)n(e)24 +b(subtree)976 b Fg(C-c)36 b($)-150 2983 y Fi(T)-6 b(o)24 b(set)g(arc)n(hiv)n(e)g(lo)r(cation)h(for)e(curren)n(t)h(\014le,)f(add) -h(a)g(line)f(lik)n(e)1495 3357 y Ff(3)1533 3380 y Fi(:)-150 -3454 y Fg(#+ARCHIVE:)38 b(archfile::*)h(Archived)e(Tasks)-150 -3631 y Fh(Filtering)g(and)g(Sparse)g(T)-10 b(rees)-150 -3781 y Fi(sho)n(w)24 b(sparse)f(tree)i(for)d(all)h(matc)n(hes)i(of)f(a) -g(regexp)92 b Fg(C-c)36 b(/)-150 3851 y Fi(view)24 b(TODO's)e(in)i -(sparse)f(tree)580 b Fg(C-c)36 b(C-v)-150 3921 y Fi(create)25 -b(sparse)e(tree)i(with)e(all)g(deadlines)i(due)204 b -Fg(C-c)36 b(C-w)-150 3991 y Fi(time)24 b(sorted)g(view)g(of)f(curren)n -(t)h(org)g(\014le)367 b Fg(C-c)36 b(C-r)-150 4060 y Fi(agenda)25 -b(for)e(the)i(w)n(eek)823 b Fg(C-c)36 b(a)p Fi(2)-150 -4130 y(agenda)25 b(for)e(date)i(at)f(cursor)661 b Fg(C-c)36 -b(C-o)2046 -364 y Fh(TODO)i(Items)2046 -215 y Fi(rotate)25 -b(the)f(state)h(of)f(the)g(curren)n(t)g(item)354 b Fg(C-c)36 -b(C-t)2046 -145 y Fi(view)24 b(TODO)f(items)g(in)h(a)g(sparse)f(tree) -380 b Fg(C-c)36 b(C-v)2046 -49 y Fi(set)24 b(the)h(priorit)n(y)e(of)g -(the)i(curren)n(t)f(item)369 b Fg(C-c)36 b(,)g([ABC])2046 -21 y Fi(remo)n(v)n(e)24 b(priorit)n(y)f(co)r(okie)i(from)d(curren)n(t)j -(item)179 b Fg(C-c)36 b(,)g(SPC)2046 102 y Fi(raise)23 -b(priorit)n(y)g(of)g(curren)n(t)i(item)557 b Fg(S-UP)3626 -78 y Ff(4)2046 182 y Fi(lo)n(w)n(er)23 b(priorit)n(y)g(of)h(curren)n(t) -g(item)538 b Fg(S-DOWN)3696 159 y Ff(4)2046 313 y Fi(p)r(er-\014le)23 +h(a)g(line)f(lik)n(e)1495 2959 y Ff(3)1533 2983 y Fi(:)-150 +3057 y Fg(#+ARCHIVE:)38 b(archfile::*)h(Archived)e(Tasks)-150 +3242 y Fh(Filtering)g(and)g(Sparse)g(T)-10 b(rees)-150 +3397 y Fi(sho)n(w)24 b(sparse)f(tree)i(for)d(all)h(matc)n(hes)i(of)f(a) +g(regexp)92 b Fg(C-c)36 b(/)-150 3467 y Fi(view)24 b(TODO's)e(in)i +(sparse)f(tree)580 b Fg(C-c)36 b(C-v)-150 3547 y Fi(global)24 +b(TODO)f(list)g(in)g(agenda)i(mo)r(de)389 b Fg(C-c)36 +b(t)1466 3524 y Ff(2)-150 3617 y Fi(create)25 b(sparse)e(tree)i(with)e +(all)g(deadlines)i(due)204 b Fg(C-c)36 b(C-w)-150 3687 +y Fi(time)24 b(sorted)g(view)g(of)f(curren)n(t)h(org)g(\014le)367 +b Fg(C-c)36 b(C-r)-150 3767 y Fi(agenda)25 b(for)e(the)i(w)n(eek)823 +b Fg(C-c)36 b(a)1466 3744 y Ff(2)-150 3837 y Fi(agenda)25 +b(for)e(date)i(at)f(cursor)661 b Fg(C-c)36 b(C-o)2046 +-364 y Fh(TODO)i(Items)2046 -215 y Fi(rotate)25 b(the)f(state)h(of)f +(the)g(curren)n(t)g(item)354 b Fg(C-c)36 b(C-t)2046 -145 +y Fi(view)24 b(TODO)f(items)g(in)h(a)g(sparse)f(tree)380 +b Fg(C-c)36 b(C-v)2046 -75 y Fi(view)24 b(3rd)f(TODO)g(k)n(eyw)n(ord's) +h(sparse)g(tree)258 b Fg(C-3)36 b(C-c)g(C-v)2046 22 y +Fi(set)24 b(the)h(priorit)n(y)e(of)g(the)i(curren)n(t)f(item)369 +b Fg(C-c)36 b(,)g([ABC])2046 91 y Fi(remo)n(v)n(e)24 +b(priorit)n(y)f(co)r(okie)i(from)d(curren)n(t)j(item)179 +b Fg(C-c)36 b(,)g(SPC)2046 172 y Fi(raise)23 b(priorit)n(y)g(of)g +(curren)n(t)i(item)557 b Fg(S-UP)3626 148 y Ff(4)2046 +252 y Fi(lo)n(w)n(er)23 b(priorit)n(y)g(of)h(curren)n(t)g(item)538 +b Fg(S-DOWN)3696 229 y Ff(4)2046 384 y Fi(p)r(er-\014le)23 b(TODO)g(w)n(ork\015o)n(w)h(states:)33 b(add)24 b(line\(s\))g(lik)n(e) -3505 290 y Ff(3)3542 313 y Fi(:)2046 386 y Fg(#+SEQ_TODO:)38 -b(TODO)f(PROCRASTINATE)i(BLUFF)e(DONE)2046 466 y Fi(p)r(er-\014le)23 +3505 360 y Ff(3)3542 384 y Fi(:)2046 457 y Fg(#+SEQ_TODO:)38 +b(TODO)f(PROCRASTINATE)i(BLUFF)e(DONE)2046 537 y Fi(p)r(er-\014le)23 b(TODO)g(k)n(eyw)n(ords:)32 b(add)24 b(line\(s\))g(lik)n(e)3314 -443 y Ff(3)3351 466 y Fi(:)2046 539 y Fg(#+TYP_TODO:)38 -b(Phil)f(home)f(work)h(DONE)2046 728 y Fh(Timestamps)2046 -877 y Fi(prompt)24 b(for)f(date)i(and)f(insert)f(timestamp)266 -b Fg(C-c)36 b(.)2046 946 y Fi(lik)n(e)23 b Fg(C-c)i Fi(.)31 -b(but)24 b(insert)g(date)g(and)h(time)e(format)144 b -Fg(C-u)36 b(C-c)g(.)2046 1016 y Fi(Lik)n(e)24 b Fg(C-c)36 +513 y Ff(3)3351 537 y Fi(:)2046 610 y Fg(#+TYP_TODO:)38 +b(Phil)f(home)f(work)h(DONE)2046 799 y Fh(Timestamps)2046 +949 y Fi(prompt)24 b(for)f(date)i(and)f(insert)f(timestamp)266 +b Fg(C-c)36 b(.)2046 1018 y Fi(lik)n(e)23 b Fg(C-c)i +Fi(.)31 b(but)24 b(insert)g(date)g(and)h(time)e(format)144 +b Fg(C-u)36 b(C-c)g(.)2046 1088 y Fi(Lik)n(e)24 b Fg(C-c)36 b(.)24 b Fi(but)g(mak)n(e)g(stamp)h(inactiv)n(e)322 b -Fg(C-c)36 b(!)2046 1086 y Fi(insert)23 b(DEADLINE)h(timestamp)516 -b Fg(C-c)36 b(C-d)2046 1156 y Fi(insert)23 b(SCHEDULED)h(timestamp)451 -b Fg(C-c)36 b(C-s)2046 1225 y Fi(create)25 b(sparse)e(tree)i(with)e -(all)g(deadlines)i(due)204 b Fg(C-c)36 b(C-w)2046 1295 +Fg(C-c)36 b(!)2046 1158 y Fi(insert)23 b(DEADLINE)h(timestamp)516 +b Fg(C-c)36 b(C-d)2046 1228 y Fi(insert)23 b(SCHEDULED)h(timestamp)451 +b Fg(C-c)36 b(C-s)2046 1297 y Fi(create)25 b(sparse)e(tree)i(with)e +(all)g(deadlines)i(due)204 b Fg(C-c)36 b(C-w)2046 1367 y Fi(the)25 b(time)e(b)r(et)n(w)n(een)j(2)e(dates)g(in)g(a)f(time)h -(range)172 b Fg(C-c)36 b(C-y)2046 1377 y Fi(c)n(hange)25 +(range)172 b Fg(C-c)36 b(C-y)2046 1449 y Fi(c)n(hange)25 b(timestamp)g(at)f(cursor)f(b)n(y)h Fe(\000)p Fi(1)g(da)n(y)238 -b Fg(S-LEFT)3696 1354 y Ff(4)2046 1458 y Fi(c)n(hange)25 +b Fg(S-LEFT)3696 1426 y Ff(4)2046 1530 y Fi(c)n(hange)25 b(timestamp)g(at)f(cursor)f(b)n(y)h(+1)g(da)n(y)238 b -Fg(S-RIGHT)3731 1434 y Ff(4)2046 1538 y Fi(c)n(hange)25 +Fg(S-RIGHT)3731 1506 y Ff(4)2046 1610 y Fi(c)n(hange)25 b(y)n(ear/mon)n(th/da)n(y)i(at)d(cursor)f(b)n(y)h Fe(\000)p -Fi(1)189 b Fg(S-DOWN)3696 1515 y Ff(4)2046 1622 y Fi(c)n(hange)25 +Fi(1)189 b Fg(S-DOWN)3696 1587 y Ff(4)2046 1694 y Fi(c)n(hange)25 b(y)n(ear/mon)n(th/da)n(y)i(at)d(cursor)f(b)n(y)h(+1)189 -b Fg(S-UP)3626 1599 y Ff(4)2046 1692 y Fi(access)25 b(the)f(calendar)g +b Fg(S-UP)3626 1671 y Ff(4)2046 1764 y Fi(access)25 b(the)f(calendar)g (for)f(the)i(curren)n(t)f(date)221 b Fg(C-c)36 b(>)2046 -1762 y Fi(insert)23 b(timestamp)i(matc)n(hing)g(date)f(in)g(calendar)89 -b Fg(C-c)36 b(<)2046 1832 y Fi(access)25 b(agenda)g(for)e(curren)n(t)h -(date)507 b Fg(C-c)36 b(C-o)2046 1901 y Fi(While)24 b(prompted)g(for)f -(a)h(date:)2046 1971 y(...)30 b(select)25 b(date)f(in)g(calendar)660 -b Fg(mouse-1/RET)2046 2041 y Fi(...)30 b(scroll)23 b(calendar)h(bac)n -(k/forw)n(ard)h(one)f(mon)n(th)121 b Fg(<)36 b(/)f(>)2046 -2111 y Fi(...)30 b(forw)n(ard/bac)n(kw)n(ard)24 b(one)h(da)n(y)525 -b Fg(S-LEFT/RIGHT)2046 2180 y Fi(...)30 b(forw)n(ard/bac)n(kw)n(ard)24 -b(one)h(w)n(eek)486 b Fg(S-UP/DOWN)2046 2250 y Fi(...)30 -b(forw)n(ard/bac)n(kw)n(ard)24 b(one)h(mon)n(th)437 b -Fg(M-S-LEFT/RIGT)2046 2449 y Fh(Links)2046 2598 y Fi(globally)24 -b(store)g(link)f(to)h(the)h(curren)n(t)f(lo)r(cation)166 -b Fg(C-c)36 b(l)3662 2574 y Ff(2)2046 2667 y Fi(insert)23 -b(a)h(link)f(\(T)-6 b(AB)24 b(completes)h(stored)f(links\))138 -b Fg(C-c)36 b(C-l)2046 2737 y Fi(insert)23 b(\014le)h(link)f(with)h -(\014le)g(name)g(completion)192 b Fg(C-u)36 b(C-c)g(C-l)2046 -2834 y Fi(op)r(en)25 b(link)e(at)h(p)r(oin)n(t)884 b -Fg(C-c)36 b(C-o)2046 2904 y Fi(op)r(en)25 b(\014le)e(links)g(in)h -(emacs)722 b Fg(C-u)36 b(C-c)g(C-o)2046 2973 y Fi(op)r(en)25 -b(link)e(at)h(p)r(oin)n(t)884 b Fg(mouse-2)2046 3043 -y Fi(op)r(en)25 b(\014le)e(links)g(in)h(emacs)722 b Fg(mouse-3)2046 -3140 y Fd(Link)27 b(t)n(yp)r(es)2046 3236 y Fg()247 b Fi(on)24 b(the)h(w)n(eb)2046 -3306 y Fg()564 b Fi(EMail)23 -b(address)2046 3376 y Fg()845 b Fi(Usenet)25 -b(group)2046 3446 y Fg()282 -b Fi(\014le,)23 b(absolute)2046 3515 y Fg()670 -b Fi(\014le,)23 b(relativ)n(e)2046 3585 y Fg()599 b Fi(\014le)19 b(with)g(line)g(nr.)2046 3655 y -Fg()631 b Fi(BBDB)23 b(p)r(erson)2046 -3725 y Fg()877 b Fi(shell)23 b(command)2046 -3794 y Fg()1020 b Fi(GNUS)24 b(group)2046 -3864 y Fg()915 b Fi(GNUS)24 b(message)2046 -3934 y Fg()1055 b Fi(VM)23 b(folder)2046 4004 -y Fg()950 b Fi(VM)23 b(message)2046 4073 -y Fg()105 -b Fi(VM)23 b(remote)2046 4143 y(W)-6 b(anderlust)25 b -Fg()h Fi(and)e(RMAIL)f Fg()k Fi(lik)n(e)c(VM)4242 --364 y Fh(T)-10 b(ables)4242 -263 y Fd(Creating)25 b(a)i(table)4242 --178 y Fi(insert)c(a)h(new)g(Org-mo)r(de)g(table)330 -b Fg(M-x)36 b(org-table-create)4242 -108 y Fi(...)30 -b(or)23 b(just)h(start)g(t)n(yping,)g(e.g.)173 b Fg(|Name|Phone|Age)39 -b(RET)d(|-)g(TAB)4242 -39 y Fi(con)n(v)n(ert)25 b(region)f(to)g(table) -741 b Fg(C-c)36 b(C-c)4242 31 y Fi(...)30 b(separator)24 -b(at)h(least)f(3)g(spaces)537 b Fg(C-3)36 b(C-c)g(C-c)4242 -116 y Fd(Commands)26 b(a)n(v)-5 b(ailable)25 b(inside)j(tables)4242 -201 y Fi(The)17 b(follo)n(wing)f(commands)i(w)n(ork)f(when)g(the)h -(cursor)e(is)g Fc(inside)k(a)f(table)p Fi(.)4242 270 -y(Outside)24 b(of)e(tables,)i(the)g(same)f(k)n(eys)h(ma)n(y)f(ha)n(v)n -(e)h(other)g(functionalit)n(y)-6 b(.)4242 355 y Fd(Re-aligning)25 +1834 y Fi(insert)23 b(timestamp)i(matc)n(hing)g(date)f(in)g(calendar)89 +b Fg(C-c)36 b(<)2046 1904 y Fi(access)25 b(agenda)g(for)e(curren)n(t)h +(date)507 b Fg(C-c)36 b(C-o)2046 1973 y Fi(Select)25 +b(date)g(while)e(prompted)598 b Fg(mouse-1/RET)2046 2169 +y Fh(Links)2046 2318 y Fi(globally)24 b(store)g(link)f(to)h(the)h +(curren)n(t)f(lo)r(cation)166 b Fg(C-c)36 b(l)3662 2295 +y Ff(2)2046 2388 y Fi(insert)23 b(a)h(link)f(\(T)-6 b(AB)24 +b(completes)h(stored)f(links\))138 b Fg(C-c)36 b(C-l)2046 +2458 y Fi(insert)23 b(\014le)h(link)f(with)h(\014le)g(name)g +(completion)192 b Fg(C-u)36 b(C-c)g(C-l)2046 2555 y Fi(op)r(en)25 +b(link)e(at)h(p)r(oin)n(t)884 b Fg(C-c)36 b(C-o)2046 +2624 y Fi(op)r(en)25 b(\014le)e(links)g(in)h(emacs)722 +b Fg(C-u)36 b(C-c)g(C-o)2046 2694 y Fi(op)r(en)25 b(link)e(at)h(p)r +(oin)n(t)884 b Fg(mouse-2)2046 2764 y Fi(op)r(en)25 b(\014le)e(links)g +(in)h(emacs)722 b Fg(mouse-3)2046 2861 y Fd(Link)27 b(t)n(yp)r(es)2046 +2957 y Fg(*CamelCaseWord)950 b Fi(searc)n(h)24 b(headline)2046 +3027 y Fg(CamelCaseWord)985 b Fi(searc)n(h)24 b(in)f(bu\013er)2046 +3097 y Fg()282 +b Fi(\014le,)23 b(absolute)2046 3167 y Fg()670 +b Fi(\014le,)23 b(relativ)n(e)2046 3236 y Fg()599 b Fi(\014le)19 b(with)g(line)g(nr.)2046 3306 y +Fg()211 +b Fi(searc)n(h)24 b(headline)2046 3376 y Fg()453 b Fi(searc)n(h)24 b(string)2046 3446 +y Fg()423 b Fi(searc)n(h)24 +b(regexp)2046 3515 y Fg()247 +b Fi(on)24 b(the)h(w)n(eb)2046 3585 y Fg() +564 b Fi(EMail)23 b(address)2046 3655 y Fg()845 +b Fi(Usenet)25 b(group)2046 3725 y Fg()631 b Fi(BBDB)23 b(p)r(erson)2046 3794 y +Fg()877 b Fi(shell)23 b(command)2046 +3864 y Fg()1020 b Fi(GNUS)24 b(group)2046 +3934 y Fg()915 b Fi(GNUS)24 b(message)2046 +4004 y Fg()1055 b Fi(VM)23 b(folder)2046 4073 +y Fg()950 b Fi(VM)23 b(message)2046 4143 +y(W)-6 b(anderlust)25 b Fg()h Fi(and)e(RMAIL)f +Fg()k Fi(lik)n(e)c(VM)4242 -364 y Fh(T)-10 +b(ables)4242 -263 y Fd(Creating)25 b(a)i(table)4242 -178 +y Fi(insert)c(a)h(new)g(Org-mo)r(de)g(table)330 b Fg(M-x)36 +b(org-table-create)4242 -108 y Fi(...)30 b(or)23 b(just)h(start)g(t)n +(yping,)g(e.g.)173 b Fg(|Name|Phone|Age)39 b(RET)d(|-)g(TAB)4242 +-39 y Fi(con)n(v)n(ert)25 b(region)f(to)g(table)741 b +Fg(C-c)36 b(C-c)4242 31 y Fi(...)30 b(separator)24 b(at)h(least)f(3)g +(spaces)537 b Fg(C-3)36 b(C-c)g(C-c)4242 116 y Fd(Commands)26 +b(a)n(v)-5 b(ailable)25 b(inside)j(tables)4242 201 y +Fi(The)17 b(follo)n(wing)f(commands)i(w)n(ork)f(when)g(the)h(cursor)e +(is)g Fc(inside)k(a)f(table)p Fi(.)4242 270 y(Outside)24 +b(of)e(tables,)i(the)g(same)f(k)n(eys)h(ma)n(y)f(ha)n(v)n(e)h(other)g +(functionalit)n(y)-6 b(.)4242 355 y Fd(Re-aligning)25 b(and)i(\014eld)h(motion)4242 440 y Fi(re-align)22 b(the)i(table)g (without)g(mo)n(ving)g(the)g(cursor)70 b Fg(C-c)36 b(C-c)4242 510 y Fi(re-align)23 b(the)h(table,)g(mo)n(v)n(e)h(to)f(next)h(\014eld) @@ -2557,67 +2549,66 @@ %%Page: 2 2 TeXDict begin @landscape 2 1 bop -169 -357 a Fj(Org-Mo)t(de)45 b(Reference)h(Card)g(\(2/2\))546 -242 y Fi(\(for)23 b(v)n(ersion)h -(3.21\))-150 -46 y Fh(Timeline)37 b(and)g(Agenda)-150 -101 y Fi(sho)n(w)24 b(timeline)f(of)h(curren)n(t)g(org)f(\014le)458 -b Fg(C-c)36 b(C-r)-150 170 y Fi(...)30 b(include)24 b(past)h(dates)793 -b Fg(C-u)36 b(C-c)g(C-r)-150 267 y Fi(add/mo)n(v)n(e)25 -b(curren)n(t)f(\014le)g(to)g(fron)n(t)g(of)f(agenda)197 -b Fg(C-c)36 b([)-150 336 y Fi(remo)n(v)n(e)24 b(curren)n(t)g(\014le)g -(from)f(y)n(our)g(agenda)299 b Fg(C-c)36 b(])-150 406 -y Fi(cycle)24 b(through)h(agenda)g(\014le)f(list)551 -b Fg(C-,)-150 487 y Fi(compile)24 b(agenda)h(for)e(the)h(curren)n(t)g -(w)n(eek)320 b Fg(C-c)36 b(a)1466 463 y Ff(2)-150 556 -y Fi(agenda)25 b(for)e(date)i(at)f(cursor)661 b Fg(C-c)36 -b(C-o)-150 687 y Fi(T)-6 b(o)24 b(set)g(category)h(for)e(curren)n(t)h -(\014le,)g(add)g(line)1082 663 y Ff(3)1119 687 y Fi(:)-150 -759 y Fg(#+CATEGORY:)38 b(MyCateg)-150 856 y Fd(Commands)26 -b(a)n(v)-5 b(ailable)25 b(in)i(an)g(agenda)g(bu\013er)-150 -952 y Fi(The)g(agenda)h(bu\013er)f(is)f(electric:)38 -b(single)26 b(k)n(ey)i(presses)e(execute)j(com-)-150 -1022 y(mands.)-150 1118 y Fd(View)e(org)f(\014le)-150 -1214 y Fi(sho)n(w)e(original)f(lo)r(cation)h(of)g(item)524 -b Fg(SPC)-150 1284 y Fi(...)30 b(also)24 b(a)n(v)l(ailable)g(with)781 -b Fg(mouse-3)-150 1353 y Fi(sho)n(w)24 b(and)g(recen)n(ter)h(windo)n(w) -626 b Fg(l)-150 1423 y Fi(goto)25 b(original)e(lo)r(cation)h(in)g -(other)g(windo)n(w)260 b Fg(TAB)-150 1493 y Fi(...)30 +(3.22\))-150 -36 y Fh(Timeline,)36 b(Agenda,)h(Global)g(TODO)h(List) +-150 120 y Fi(sho)n(w)24 b(timeline)f(of)h(curren)n(t)g(org)f(\014le) +458 b Fg(C-c)36 b(C-r)-150 190 y Fi(...)30 b(include)24 +b(past)h(dates)793 b Fg(C-u)36 b(C-c)g(C-r)-150 288 y +Fi(add/mo)n(v)n(e)25 b(curren)n(t)f(\014le)g(to)g(fron)n(t)g(of)f +(agenda)197 b Fg(C-c)36 b([)-150 358 y Fi(remo)n(v)n(e)24 +b(curren)n(t)g(\014le)g(from)f(y)n(our)g(agenda)299 b +Fg(C-c)36 b(])-150 427 y Fi(cycle)24 b(through)h(agenda)g(\014le)f +(list)551 b Fg(C-,)-150 508 y Fi(compile)24 b(agenda)h(for)e(the)h +(curren)n(t)g(w)n(eek)320 b Fg(C-c)36 b(a)1466 485 y +Ff(2)-150 578 y Fi(agenda)25 b(for)e(date)i(at)f(cursor)661 +b Fg(C-c)36 b(C-o)-150 658 y Fi(global)24 b(TODO)f(list)899 +b Fg(C-c)36 b(t)1466 635 y Ff(2)-150 791 y Fi(T)-6 b(o)24 +b(set)g(category)h(for)e(curren)n(t)h(\014le,)g(add)g(line)1082 +767 y Ff(3)1119 791 y Fi(:)-150 866 y Fg(#+CATEGORY:)38 +b(MyCateg)-150 964 y Fd(Commands)26 b(a)n(v)-5 b(ailable)25 +b(in)i(an)g(agenda)g(bu\013er)-150 1062 y(View)g(org)f(\014le)-150 +1161 y Fi(sho)n(w)e(original)f(lo)r(cation)h(of)g(item)524 +b Fg(SPC)-150 1230 y Fi(...)30 b(also)24 b(a)n(v)l(ailable)g(with)781 +b Fg(mouse-3)-150 1300 y Fi(sho)n(w)24 b(and)g(recen)n(ter)h(windo)n(w) +626 b Fg(l)-150 1370 y Fi(goto)25 b(original)e(lo)r(cation)h(in)g +(other)g(windo)n(w)260 b Fg(TAB)-150 1439 y Fi(...)30 b(also)24 b(a)n(v)l(ailable)g(with)781 b Fg(mouse-2)-150 -1563 y Fi(goto)25 b(original)e(lo)r(cation,)h(delete)h(other)f(windo)n -(ws)91 b Fg(RET)-150 1632 y Fi(toggle)25 b(follo)n(w-mo)r(de)861 -b Fg(f)-150 1729 y Fd(Change)27 b(displa)n(y)-150 1825 -y Fi(delete)e(other)f(windo)n(ws)791 b Fg(o)-150 1895 +1509 y Fi(goto)25 b(original)e(lo)r(cation,)h(delete)h(other)f(windo)n +(ws)91 b Fg(RET)-150 1579 y Fi(toggle)25 b(follo)n(w-mo)r(de)861 +b Fg(f)-150 1677 y Fd(Change)27 b(displa)n(y)-150 1776 +y Fi(delete)e(other)f(windo)n(ws)791 b Fg(o)-150 1845 y Fi(switc)n(h)24 b(to)g(w)n(eekly)h(view)767 b Fg(w)-150 -1964 y Fi(switc)n(h)24 b(to)g(daily)g(view)822 b Fg(d)-150 -2034 y Fi(toggle)25 b(inclusion)e(of)h(diary)f(en)n(tries)473 -b Fg(D)-150 2104 y Fi(toggle)25 b(time)f(grid)f(for)g(daily)g(sc)n -(hedule)388 b Fg(g)-150 2174 y Fi(refresh)23 b(agenda)i(bu\013er)f -(with)g(an)n(y)g(c)n(hanges)239 b Fg(r)-150 2243 y Fi(displa)n(y)24 +1915 y Fi(switc)n(h)24 b(to)g(daily)g(view)822 b Fg(d)-150 +1985 y Fi(toggle)25 b(inclusion)e(of)h(diary)f(en)n(tries)473 +b Fg(D)-150 2055 y Fi(toggle)25 b(time)f(grid)f(for)g(daily)g(sc)n +(hedule)388 b Fg(g)-150 2124 y Fi(refresh)23 b(agenda)i(bu\013er)f +(with)g(an)n(y)g(c)n(hanges)239 b Fg(r)-150 2194 y Fi(displa)n(y)24 b(the)g(follo)n(wing)f Fg(org-agenda-ndays)221 b(RIGHT)-150 -2313 y Fi(displa)n(y)24 b(the)g(previous)g Fg(org-agenda-ndays)238 -b(LEFT)-150 2383 y Fi(goto)25 b(to)r(da)n(y)1110 b Fg(.)-150 -2479 y Fd(Remote)27 b(editing)-150 2575 y Fi(digit)d(argumen)n(t)984 -b Fg(0-9)-150 2671 y Fi(c)n(hange)25 b(state)g(of)f(curren)n(t)g(TODO)f -(item)333 b Fg(t)-150 2741 y Fi(set)24 b(priorit)n(y)f(of)g(curren)n(t) -i(item)612 b Fg(p)-150 2823 y Fi(raise)23 b(priorit)n(y)g(of)g(curren)n -(t)i(item)557 b Fg(S-UP)1430 2800 y Ff(4)-150 2904 y +2264 y Fi(displa)n(y)24 b(the)g(previous)g Fg(org-agenda-ndays)238 +b(LEFT)-150 2334 y Fi(goto)25 b(to)r(da)n(y)1110 b Fg(.)-150 +2432 y Fd(Remote)27 b(editing)-150 2530 y Fi(digit)d(argumen)n(t)984 +b Fg(0-9)-150 2629 y Fi(c)n(hange)25 b(state)g(of)f(curren)n(t)g(TODO)f +(item)333 b Fg(t)-150 2698 y Fi(set)24 b(priorit)n(y)f(of)g(curren)n(t) +i(item)612 b Fg(p)-150 2781 y Fi(raise)23 b(priorit)n(y)g(of)g(curren)n +(t)i(item)557 b Fg(S-UP)1430 2757 y Ff(4)-150 2861 y Fi(lo)n(w)n(er)23 b(priorit)n(y)g(of)h(curren)n(t)g(item)538 -b Fg(S-DOWN)1500 2880 y Ff(4)-150 2974 y Fi(displa)n(y)24 +b Fg(S-DOWN)1500 2838 y Ff(4)-150 2931 y Fi(displa)n(y)24 b(w)n(eigh)n(ted)h(priorit)n(y)e(of)g(curren)n(t)h(item)189 -b Fg(P)-150 3080 y Fi(c)n(hange)25 b(timestamp)g(to)f(one)g(da)n(y)h -(earlier)315 b Fg(S-LEFT)1500 3057 y Ff(4)-150 3161 y +b Fg(P)-150 3040 y Fi(c)n(hange)25 b(timestamp)g(to)f(one)g(da)n(y)h +(earlier)315 b Fg(S-LEFT)1500 3016 y Ff(4)-150 3120 y Fi(c)n(hange)25 b(timestamp)g(to)f(one)g(da)n(y)h(later)367 -b Fg(S-RIGHT)1535 3137 y Ff(4)-150 3231 y Fi(c)n(hange)25 -b(timestamp)g(to)f(to)r(da)n(y)598 b Fg(>)-150 3327 y +b Fg(S-RIGHT)1535 3097 y Ff(4)-150 3190 y Fi(c)n(hange)25 +b(timestamp)g(to)f(to)r(da)n(y)598 b Fg(>)-150 3288 y Fi(insert)23 b(new)i(en)n(try)f(in)n(to)g(diary)612 b -Fg(i)-150 3423 y Fd(Calendar)26 b(commands)-150 3519 +Fg(i)-150 3387 y Fd(Calendar)26 b(commands)-150 3485 y Fi(\014nd)e(agenda)h(cursor)f(date)g(in)g(calendar)350 -b Fg(c)-150 3589 y Fi(compute)25 b(agenda)g(for)e(calendar)i(cursor)e -(date)180 b Fg(c)-150 3659 y Fi(sho)n(w)24 b(phases)g(of)f(the)i(mo)r -(on)669 b Fg(M)-150 3728 y Fi(sho)n(w)24 b(sunrise/sunset)g(times)636 -b Fg(S)-150 3798 y Fi(sho)n(w)24 b(holida)n(ys)1014 b -Fg(H)-150 3868 y Fi(con)n(v)n(ert)25 b(date)g(to)f(other)g(calendars) -478 b Fg(C)-150 3964 y Fd(Quit)27 b(and)g(Exit)-150 4060 +b Fg(c)-150 3555 y Fi(compute)25 b(agenda)g(for)e(calendar)i(cursor)e +(date)180 b Fg(c)-150 3624 y Fi(sho)n(w)24 b(phases)g(of)f(the)i(mo)r +(on)669 b Fg(M)-150 3694 y Fi(sho)n(w)24 b(sunrise/sunset)g(times)636 +b Fg(S)-150 3764 y Fi(sho)n(w)24 b(holida)n(ys)1014 b +Fg(H)-150 3834 y Fi(con)n(v)n(ert)25 b(date)g(to)f(other)g(calendars) +478 b Fg(C)-150 3932 y Fd(Quit)27 b(and)g(Exit)-150 4030 y Fi(quit)d(agenda,)h(remo)n(v)n(e)f(agenda)h(bu\013er)376 -b Fg(q)-150 4130 y Fi(exit)24 b(agenda,)h(remo)n(v)n(e)f(all)f(agenda)i +b Fg(q)-150 4100 y Fi(exit)24 b(agenda,)h(remo)n(v)n(e)f(all)f(agenda)i (bu\013ers)258 b Fg(x)2046 -364 y Fh(Exp)s(orting)2046 -229 y Fi(Exp)r(orting)32 b(creates)g(\014les)g(with)f(extensions)i Fc(.txt)k Fi(and)32 b Fc(.html)38 b Fi(in)31 b(the)2046 @@ -2750,7 +2741,7 @@ Fg(org-CUA-compatibility)p Fi(.)4535 3770 y Fb(Cop)n(yrigh)n(t)4838 3768 y(c)4821 3770 y Fa(\015)d Fb(2005)i(F)-5 b(ree)21 b(Soft)n(w)n(are)i(F)-5 b(oundation,)20 b(Inc.)4795 3826 -y(v3.21)h(for)h(Org-Mo)r(de)e(3.21,)i(2005)4912 3882 +y(v3.22)h(for)h(Org-Mo)r(de)e(3.22,)i(2005)4912 3882 y(Author:)k(Philip)18 b(Ro)r(ok)n(e)4473 3937 y(based)j(on)g(refcard)g (design)g(and)f(format)i(b)n(y)f(Stephen)f(Gildea)4242 4022 y(P)n(ermission)28 b(is)f(gran)n(ted)i(to)f(mak)n(e)h(and)e diff -r 8e25aa911e3e -r 37d0562504bf etc/orgcard.tex --- a/etc/orgcard.tex Sat Dec 10 21:12:12 2005 +0000 +++ b/etc/orgcard.tex Sat Dec 10 21:18:28 2005 +0000 @@ -1,4 +1,4 @@ -% Reference Card for Org Mode 3.21 +% Reference Card for Org Mode 3.22 % %**start of header \newcount\columnsperpage @@ -58,7 +58,7 @@ % Thanks to Paul Rubin, Bob Chassell, Len Tower, and Richard Mlynarik % for their many good ideas. -\def\orgversionnumber{3.21} +\def\orgversionnumber{3.22} \def\year{2005} \def\shortcopyrightnotice{\vskip 1ex plus 2 fill @@ -270,18 +270,20 @@ \section{Getting Started} % -Put the following in your \kbd{~/.emacs}$^1$ +%Put the following in your \kbd{~/.emacs}$^1$ \vskip -1mm \beginexample% -(autoload 'org-mode "org" "Org mode" t) -(autoload 'org-diary "org" "Org mode diary entries") -(autoload 'org-agenda "org" "Agenda from Org files" t) -(autoload 'org-store-link "org" "Store org link" t) -(autoload 'orgtbl-mode "org" "Orgtbl minor mode" t) -(autoload 'turn-on-orgtbl "org" "Orgtbl minor mode") +%(autoload 'org-mode "org" "Org mode" t) +%(autoload 'org-diary "org" "Org mode diary entries") +%(autoload 'org-agenda "org" "Agenda from Org files" t) +%(autoload 'org-todo-list "org" "Global TODO list" t) +%(autoload 'org-store-link "org" "Store org link" t) +%(autoload 'orgtbl-mode "org" "Orgtbl minor mode" t) +%(autoload 'turn-on-orgtbl "org" "Orgtbl minor mode") (add-to-list 'auto-mode-alist '("\\\\.org\$" . org-mode)) (define-key global-map "\\C-cl" 'org-store-link)$^2$ (define-key global-map "\\C-ca" 'org-agenda)$^2$ +(define-key global-map "\\C-ct" 'org-todo-list)$^2$ \endexample % \metax{For the many customization options try}{M-x org-customize} @@ -330,15 +332,17 @@ \key{show sparse tree for all matches of a regexp}{C-c /} \key{view TODO's in sparse tree}{C-c C-v} +\key{global TODO list in agenda mode}{C-c t$^2$} \key{create sparse tree with all deadlines due}{C-c C-w} \key{time sorted view of current org file}{C-c C-r} -\key{agenda for the week}{C-c a$2$} +\key{agenda for the week}{C-c a$^2$} \key{agenda for date at cursor}{C-c C-o} \section{TODO Items} \key{rotate the state of the current item}{C-c C-t} \key{view TODO items in a sparse tree}{C-c C-v} +\key{view 3rd TODO keyword's sparse tree}{C-3 C-c C-v} \key{set the priority of the current item}{C-c , [ABC]} \key{remove priority cookie from current item}{C-c , SPC} @@ -374,12 +378,12 @@ \key{access the calendar for the current date}{C-c >} \key{insert timestamp matching date in calendar}{C-c <} \key{access agenda for current date}{C-c C-o} -\key{While prompted for a date:}{} -\key{... select date in calendar}{mouse-1/RET} -\key{... scroll calendar back/forward one month}{< / >} -\key{... forward/backward one day}{S-LEFT/RIGHT} -\key{... forward/backward one week}{S-UP/DOWN} -\key{... forward/backward one month}{M-S-LEFT/RIGT} +\key{Select date while prompted}{mouse-1/RET} +%\key{... select date in calendar}{mouse-1/RET} +%\key{... scroll calendar back/forward one month}{< / >} +%\key{... forward/backward one day}{S-LEFT/RIGHT} +%\key{... forward/backward one week}{S-UP/DOWN} +%\key{... forward/backward one month}{M-S-LEFT/RIGT} \section{Links} @@ -394,19 +398,25 @@ {\bf Link types} +\key{\kbd{*CamelCaseWord}}{\rm search headline} +\key{\kbd{CamelCaseWord}}{\rm search in buffer} +\key{\kbd{}}{\rm file, absolute} +\key{\kbd{}}{\rm file, relative} +\key{\kbd{}}{\rm file with line nr.} +\key{\kbd{}}{\rm search headline} +\key{\kbd{}}{\rm search string} +\key{\kbd{}}{\rm search regexp} \key{\kbd{}}{\rm on the web} \key{\kbd{}}{\rm EMail address} \key{\kbd{}}{\rm Usenet group} -\key{\kbd{}}{\rm file, absolute} -\key{\kbd{}}{\rm file, relative} -\key{\kbd{}}{\rm file with line nr.} \key{\kbd{}}{\rm BBDB person} \key{\kbd{}}{\rm shell command} \key{\kbd{}}{\rm GNUS group} \key{\kbd{}}{\rm GNUS message} \key{\kbd{}}{\rm VM folder} \key{\kbd{}}{\rm VM message} -\key{\kbd{}}{\rm VM remote} +% FIXME: would like to get this back in. +%\key{\kbd{}}{\rm VM remote} Wanderlust \kbd{} and RMAIL \kbd{} like VM %\key{\kbd{}}{\rm Wanderlust f.} %\key{\kbd{}}{\rm Wanderlust m.} @@ -506,7 +516,7 @@ \centerline{(for version \orgversionnumber)} -\section{Timeline and Agenda} +\section{Timeline, Agenda, Global TODO List} \key{show timeline of current org file}{C-c C-r} \key{... include past dates}{C-u C-c C-r} @@ -516,6 +526,7 @@ \key{cycle through agenda file list}{C-,} \key{compile agenda for the current week}{C-c a$^2$} \key{agenda for date at cursor}{C-c C-o} +\key{global TODO list}{C-c t$^2$} \vskip 1mm To set category for current file, add line$^3$: \vskip -1mm @@ -525,8 +536,6 @@ {\bf Commands available in an agenda buffer} -The agenda buffer is electric: single key presses execute commands. - {\bf View org file} \key{show original location of item}{SPC} diff -r 8e25aa911e3e -r 37d0562504bf lisp/ChangeLog --- a/lisp/ChangeLog Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/ChangeLog Sat Dec 10 21:18:28 2005 +0000 @@ -1,3 +1,320 @@ +2005-12-08 Kenichi Handa + + * descr-text.el (describe-char): Use *Help-2* buffer if the + current buffer is *Help*. Call describe-text-properties while + setting the original buffer. + +2005-12-07 Bill Wohler + + * files.el (auto-mode-alist): Remove mh-letter-mode. Unnecessary, + and causes problems with non-MH users (such as Gnus users). + +2005-12-08 Nick Roberts + + * progmodes/gdb-ui.el (gdb-find-file-unhook): Delete variable. + (gdb-set-gud-minor-mode, gdb-set-gud-minor-mode): Delete functions. + (gdb-set-gud-minor-mode-existing-buffers, gdb-init-2): Use GDB + command "info sources". Move calls to GDB command "list". + (gdb-find-file-hook): Just use gdb-source-file-list. + (gdb-source-file-regexp): Use regexp for pre-GDB 6.4. + (gdb-source-file-regexp-1): New regexp for GDB 6.4+ only. + (gdb-set-gud-minor-mode-existing-buffers-1): Use it. + (gdb-data-list-register-values-handler): Use correct trigger name. + +2005-12-07 Kim F. Storm + + * ido.el (ido-completion-map): Renamed from ido-mode-map. + (ido-common-completion-map, ido-file-completion-map) + (ido-file-dir-completion-map, ido-buffer-completion-map): + Renamed from ido-mode-....-map. + (ido-init-completion-maps): Renamed from ido-init-mode-maps. + (ido-setup-completion-map): Renamed from ido-define-mode-map. + (ido-read-internal): Bind minibuffer-local-filename-completion-map + to ido-completion-map. + +2005-12-07 Kenichi Handa + + * international/mule-cmds.el + (set-display-table-and-terminal-coding-system): If the coding + system specified in `unibyte-display' property is different from + the arg coding-system, don't setup standard-display-table. + +2005-12-06 Stefan Monnier + + * emacs-lisp/edebug.el (edebug-skip-whitespace): read1:lread.c says + that comments end at \n, regardless of selective-display. + +2005-12-07 Nick Roberts + + * progmodes/gdb-ui.el (gdb-error-regexp, gdb-first-post-prompt) + (gdb-version): New variables. + (gdb-source-file-list, gdb-register-names) + (gdb-changed-registers): New variables for use with GDB 6.4+. + (gdb-ann3): Replace with... + (gdb-init-1, gdb-init-2): ...two new functions. + (gdba, gdb-prompt): Call gdb-init-1. + (gdb-get-version): New function. Call gdb-init-2 from here. + (gud-watch): Make it work with mouse events too. + (gdb-post-prompt): Don't add to queue until GDB version is known. + (gdb-speedbar-expand-node, gdb-post-prompt, gdb-registers-mode) + (gdb-locals-mode): Use gdb-version. + (gdb-memory-format-map, gdb-memory-unit-map) + (gdb-locals-watch-map): Rename from gdb-*-*-keymap. + (gdb-locals-font-lock-keywords-1) + (gdb-locals-font-lock-keywords-2): New variables. + (gdb-find-file-hook): fgfg. + (gdb-set-gud-minor-mode-existing-buffers-1) + (gdb-var-list-children-1, gdb-var-list-children-handler-1) + (gdb-var-update-1, gdb-var-update-handler-1) + (gdb-data-list-register-values-handler) + (gdb-data-list-register-values-custom) + (gdb-get-changed-registers, gdb-get-changed-registers-handler) + (gdb-stack-list-locals-handler, gdb-get-register-names): + New functions for use with GDB 6.4+. + (gdb-locals-watch-map-1): New variable for use with GDB 6.4+. + (gdb-source-file-regexp, gdb-var-list-children-regexp-1) + (gdb-var-update-regexp-1, gdb-data-list-register-values-regexp) + (gdb-stack-list-locals-regexp) + (gdb-data-list-register-names-regexp): New regexps for use with + GDB 6.4+. + +2005-12-06 Stefan Monnier + + * progmodes/cc-defs.el (c-emacs-features): Don't assume point-min==1. + +2005-12-06 Nozomu Ando (tiny patch) + + * mail/smtpmail.el (smtpmail-try-auth-methods): Make password + prompts work for AUTH PLAIN. Also reported by Steve Allan + . + +2005-12-06 L$,1 q(Brentey K,Aa(Broly + + * frame.el (set-frame-parameter): Add doc string. + +2005-12-06 Carsten Dominik + + * textmodes/org.el: (org-occur-highlights): New variable. + (org-highlight-new-match, org-remove-occur-highlights): New functions. + (org-highlight-sparse-tree-matches): New option. + (org-do-occur): New function. + (org-get-heading): Make it work also at beginning of line. + (org-category-table): New variable. + (org-get-category-table, org-get-category) + (org-camel-to-words, org-link-search): New functions. + (org-select-this-todo-keyword): New variable. + (org-todo-list): New command. + (org-shiftright, org-shiftleft): New commands. + (org-agenda-todo): Add prefix argument. + (org-show-hierarchy-above): New option. + (org-show-todo-tree): Numerical prefix creates tree for specific + TODO keyword. + (org-outline-level): New function, to assign a level to plain + lists items. + (org-cycle-include-plain-lists): New option. + (org-mode): Use `org-outline-level' as value of `outline-level'. + (org-cycle): Temporarily switch `outline-regexp' if + `org-cycle-include-plain-lists' is non-nil. + (org-start-icalendar-file): Fix format bug. + (org-agenda-get-day-entries): Create category table. + (org-agenda-get-todos, org-agenda-get-timestamps) + (org-agenda-get-deadlines, org-agenda-get-scheduled) + (org-agenda-get-blocks): Use `org-get-category'. + (org-context-in-file-links): Rename from + `org-line-numbers-in-file-links' . + +2005-12-06 Romain Francoise + + * window.el (balance-windows): Delete extraneous third arg in call + to `enlarge-window'. + +2005-12-06 Kenichi Handa + + * international/kinsoku.el (kinsoku-longer): Check eolp, not eobp. + +2005-12-06 Nick Roberts + + * progmodes/gdb-ui.el (gdb-var-create-handler) + (gdb-var-evaluate-expression-handler, gdb-frame-handler) + (gdb-var-list-children-handler, gdb-var-update-handler): + Current buffer is already gdb-partial-output-buffer, don't + make it current again. + +2005-12-05 Luc Teirlinck + + * buff-menu.el (Buffer-menu-use-frame-buffer-list): New user option. + (list-buffers-noselect): Use it. + +2005-12-05 Stefan Monnier + + * mail/sendmail.el: Remove unnecessary leading-star in docstrings. + (mail-yank-ignored-headers): Use regexp-opt. + (mail-mode-map): Move initialization into declaration. + (mail-sent-via): Remove unused shadowed var `to-line'. + (mail-mailer-swallows-blank-line): Use with-temp-buffer. + (mail-bury, sendmail-send-it, mail-do-fcc): Use with-current-buffer. + (mail-do-fcc): Use dolist and push. + (mail-mode-fill-paragraph): Pass the arg to fill-region-as-paragraph. + (mail-yank-ignored-headers): Don't autoload. + +2005-12-05 Kenichi Handa + + * international/mule-cmds.el (set-language-info-internal): New fun. + (set-language-info): Call set-language-info-internal to update + language-info-alist. If LANG-ENV is the current one, call + set-language-environment to make INFO effective now. + (set-language-info-alist): Likewise. + (locale-language-names): With locale "en", use English + lang. env. but set the default codings to iso-8859-1. + +2005-12-04 Nick Roberts + + * progmodes/gdb-ui.el (gdb-use-inferior-io-buffer) + (gdb-speedbar-auto-raise): Echo new state in minibuffer. + (gdb-var-create-handler, gdb-assembler-custom): Use search-forward + for plain strings. + (gdb-frames-mode): Remove redundant call to font-lock-mode. + (gdb-all-registers): Rename from toggle-gdb-all-registers. + Create registers buffer if necessary. Echo new state in minibuffer. + (gdb-registers-mode-map, gdb-registers-mode): Use gdb-all-registers. + +2005-12-03 Chong Yidong + + * info.el (Info-fontify-node): Match external links using + non-directory part of filename. + +2005-12-04 Juri Linkov + + * font-core.el (global-font-lock-mode): Use define-global-minor-mode + instead of easy-mmode-define-global-mode. Add `:group font-lock'. + (font-lock-mode): Replace `:group font-lock' with `nil nil nil'. + + * font-lock.el (lisp-font-lock-keywords-1): + Add define-global-minor-mode. + + * emacs-lisp/autoload.el (make-autoload): Add define-global-minor-mode. + + * emacs-lisp/derived.el (define-derived-mode): Put `definition-name' + properties on the constructed variable names. + + * emacs-lisp/easy-mmode.el (easy-mmode-define-navigation): + Put `definition-name' properties on the constructed function names + next-sym and prev-sym. + + * emacs-lisp/find-func.el (find-function-regexp): + Add define-global-minor-mode. Replace `easy-mmode-define-global-mode' + with `easy-mmode-define-[a-z-]+'. Add easy-menu-define. + (find-variable-regexp): Add easy-mmode-defmap, easy-mmode-defsyntax + and easy-menu-define. + + * emacs-lisp/lisp-mode.el: Put `doc-string-elt' property on + easy-mmode-define-global-mode and define-global-minor-mode. + (lisp-imenu-generic-expression): Add define-global-minor-mode. + + * progmodes/cwarn.el (global-cwarn-mode): Use define-global-minor-mode + instead of easy-mmode-define-global-mode. + + * progmodes/idlw-shell.el (idlwave-shell-electric-debug-mode): + Use define-minor-mode instead of easy-mmode-define-minor-mode. + + * cus-edit.el (customize-group, customize-group-other-window): + Filter out autoloaded options from the group completion list by + using heuristics that autoloaded groups don't have `custom-autoload' + property on their symbols (they have only `custom-loads'). + + * simple.el (completion-setup-function): Put completions-common-part + face on full completion string too (i.e. completion string without + completions-first-difference face). + + * man.el (Man-section-regexp): Add 0-9 to support "3X11" sections. + +2005-12-03 Eli Zaretskii + + * view.el (view-mode): Doc fix. + + * disp-table.el (standard-display-european): Add to the warning + message a reference to the doc string. + + * play/yow.el (apropos-zippy): Call print-help-return-message, + similar to other Help and Apropos commands. + + * help.el (print-help-return-message): If pop-up-frames is + non-nil, set up help-return-method to delete the help window and, + possibly, its frame as well, and don't display message about + scrolling the help window. Doc fix. + (help-return-method): Doc fix. + +2005-12-03 Martin Rudalics (tiny change) + + * emacs-lisp/lisp-mode.el (lisp-imenu-generic-expression): Fix bug + whereby names of length one or names starting with a + symbol-constituent character would not be returned. + +2005-12-03 Johan Bockg,Ae(Brd + + * subr.el (atomic-change-group): Add edebug and indentation spec. + +2005-12-02 Stefan Monnier + + * completion.el (save-completions-file-name): Fix typo in last change. + +2005-12-02 Jan Dj,Ad(Brv + + * info.el: Move back/forward history to the beginning of the tool bar. + +2005-12-02 Ken Manheimer + + * allout.el:(eval-when-compile): Remove unnecessary load of 'cl. + Add fset of allout-real-isearch-abort during compile to fix + byte-compilation warnings. + (allout-mode-p): Move definition of this macro above all uses, or + byte compilation in barren emacs (eg, during emacs build) will + lack the definition. + (allout-mode): Move this variable above any uses, or byte + compilation will fail. + (allout-resolve-xref): Remove use of personal file-reference function. + (allout-toggle-current-subtree-encryption): Do the current (ie, + visible containing) topic, rather than nearest around point. Doc fix. + (allout-toggle-subtree-encryption): New function, workhorse that + works on nearest topic containing point. + (allout-encrypt-string): Signal requirement for newer version of pgg. + (allout-resumptions): Doc fix. + +2005-12-02 Eli Zaretskii + + * international/latexenc.el (latex-inputenc-coding-alist): Doc fix. + +2005-12-02 Agustin Martin + + * textmodes/flyspell.el (flyspell-external-point-words): + Consider a misspelling as found in the string search if: (a) misspelling + and found string lengths match, or (b) misspelling is found as + element in a boundary-chars separated longer string, or (c) + ispell-program-name is really ispell and misspelling is found as + part of a TeX string. After successful match move beginning of + search region to end of match. Warn about not found misspellings + once the process is done. + (flyspell-large-region): Do not set ispell-parser to tex if in TeX mode. + +2005-12-02 Nick Roberts + + * progmodes/gud.el (gud-menu-map): Put gud-finish back on the + tool bar (removed inadvertently). + +2005-12-02 Juri Linkov + + * log-view.el (log-view-diff): Clarify doc string. + +2005-12-01 Bill Wohler + + * Makefile.in (mh-loaddefs.el): Reinsert Change Log as its absence + triggers lm-verify errors. + +2005-12-01 Luc Teirlinck + + * simple.el (transient-mark-mode, line-number-mode) + (column-number-mode, size-indication-mode): Remove `:require nil'. + 2005-12-01 Nick Roberts * progmodes/gdb-ui.el (gdb-ann3): Bind mouse-2 to gdb-mouse-until @@ -18,7 +335,7 @@ (speedbar-frame-reposition-smartly): Use it. * dframe.el (dframe-reposition-frame-emacs): Fix position - computation for 'left location. + computation for `left' location. Update copyright year. 2005-11-30 Stefan Monnier diff -r 8e25aa911e3e -r 37d0562504bf lisp/Makefile.in --- a/lisp/Makefile.in Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/Makefile.in Sat Dec 10 21:18:28 2005 +0000 @@ -235,6 +235,7 @@ echo ";; Author: Bill Wohler " >> $@ echo ";; Keywords: mail" >> $@ echo ";;; Commentary:" >> $@ + echo ";;; Change Log:" >> $@ echo ";;; Code:" >> $@ $(EMACS) $(EMACSOPT) \ -l autoload \ diff -r 8e25aa911e3e -r 37d0562504bf lisp/allout.el --- a/lisp/allout.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/allout.el Sat Dec 10 21:18:28 2005 +0000 @@ -80,9 +80,11 @@ (provide 'allout) ;;;_* Dependency autoloads -(eval-when-compile 'cl) ; otherwise, flet compilation fouls (eval-when-compile (progn (require 'pgg) - (require 'pgg-gpg))) + (require 'pgg-gpg) + (fset 'allout-real-isearch-abort + (symbol-function 'isearch-abort)) + )) (autoload 'pgg-gpg-symmetric-key-p "pgg-gpg" "True if decoded armor MESSAGE-KEYS has symmetric encryption indicator.") @@ -585,8 +587,7 @@ is nil. Operations potentially causing edits include allout encryption routines. -See the docstring for `allout-toggle-current-subtree-encryption' for -details." +For details, see `allout-toggle-current-subtree-encryption's docstring." :type 'boolean :group 'allout) (make-variable-buffer-local 'allout-enable-file-variable-adjustment) @@ -606,6 +607,10 @@ (if here (insert msg)) (message "%s" msg) msg)) +;;;_ : Mode activation (defined here because it's referenced early) +;;;_ = allout-mode +(defvar allout-mode nil "Allout outline mode minor-mode flag.") +(make-variable-buffer-local 'allout-mode) ;;;_ : Topic header format ;;;_ = allout-regexp (defvar allout-regexp "" @@ -898,7 +903,7 @@ First arg is NAME of variable affected. Optional second arg is list containing allout-mode-specific VALUE to be imposed on named -variable, and to be registered. (It's a list so you can specify +variable, and to be registered. \(It's a list so you can specify registrations of null values.) If no value is specified, the registered value is returned (encapsulated in the list, so the caller can distinguish nil vs no value), and the registration is popped @@ -1033,6 +1038,12 @@ This is used to decrypt the topic that was currently being edited, if it was encrypted automatically as part of a file write or autosave.") (make-variable-buffer-local 'allout-after-save-decrypt) +;;;_ > allout-mode-p () +;; Must define this macro above any uses, or byte compilation will lack +;; proper def, if file isn't loaded - eg, during emacs build! +(defmacro allout-mode-p () + "Return t if `allout-mode' is active in current buffer." + 'allout-mode) ;;;_ > allout-write-file-hook-handler () (defun allout-write-file-hook-handler () "Implement `allout-encrypt-unencrypted-on-saves' policy for file writes." @@ -1061,7 +1072,7 @@ nil) ;;;_ > allout-auto-save-hook-handler () (defun allout-auto-save-hook-handler () - "Implement `allout-encrypt-unencrypted-on-saves' policy for auto saves." + "Implement `allout-encrypt-unencrypted-on-saves' policy for auto save." (if (and (allout-mode-p) allout-encrypt-unencrypted-on-saves) ;; Always implement 'except-current policy when enabled. @@ -1082,7 +1093,7 @@ t (goto-char (car allout-after-save-decrypt)) (let ((was-modified (buffer-modified-p))) - (allout-toggle-current-subtree-encryption) + (allout-toggle-subtree-encryption) (if (not was-modified) (set-buffer-modified-p nil))) (goto-char (cadr allout-after-save-decrypt)) @@ -1090,13 +1101,6 @@ ) ;;;_ #2 Mode activation -;;;_ = allout-mode -(defvar allout-mode () "Allout outline mode minor-mode flag.") -(make-variable-buffer-local 'allout-mode) -;;;_ > allout-mode-p () -(defmacro allout-mode-p () - "Return t if `allout-mode' is active in current buffer." - 'allout-mode) ;;;_ = allout-explicitly-deactivated (defvar allout-explicitly-deactivated nil "If t, `allout-mode's last deactivation was deliberate. @@ -1297,7 +1301,7 @@ encryption, encryption with a mistaken passphrase, forgetting which passphrase was used, and other practical pitfalls. -See the `allout-toggle-current-subtree-encryption' function and +See `allout-toggle-current-subtree-encryption' function docstring and `allout-encrypt-unencrypted-on-saves' customization variable for details. HOT-SPOT Operation @@ -1404,12 +1408,10 @@ (or (and (listp toggle)(car toggle)) toggle))) ; Activation specifically demanded? - (explicit-activation (or - ;; - (and toggle + (explicit-activation (and toggle (or (symbolp toggle) - (and (natnump toggle) - (not (zerop toggle))))))) + (and (wholenump toggle) + (not (zerop toggle)))))) ;; allout-mode already called once during this complex command? (same-complex-command (eq allout-v18/19-file-var-hack (car command-history))) @@ -3714,14 +3716,7 @@ (setq file-name (if (re-search-forward "\\s-\\(\\S-*\\)" heading-end t) (buffer-substring (match-beginning 1) (match-end 1)))))) - (setq file-name - (if (not (= (aref file-name 0) ?:)) - (expand-file-name file-name) - ; A registry-files ref, strip the `:' - ; and try to follow it: - (let ((reg-ref (reference-registered-file - (substring file-name 1) nil t))) - (if reg-ref (car (cdr reg-ref)))))) + (setq file-name (expand-file-name file-name)) (if (or (file-exists-p file-name) (if (file-writable-p file-name) (y-or-n-p (format "%s not there, create one? " @@ -4851,13 +4846,13 @@ ;;;_ #8 Encryption ;;;_ > allout-toggle-current-subtree-encryption (&optional fetch-pass) (defun allout-toggle-current-subtree-encryption (&optional fetch-pass) - "Encrypt clear text or decrypt encoded topic contents \(body and subtopics.) + "Encrypt clear or decrypt encoded text of visibly-containing topic's contents. Optional FETCH-PASS universal argument provokes key-pair encryption with single universal argument. With doubled universal argument \(value = 16), it forces prompting for the passphrase regardless of availability from the passphrase cache. With no universal argument, the appropriate passphrase -for the is obtained from the cache, if available, else from the user. +is obtained from the cache, if available, else from the user. Currently only GnuPG encryption is supported. @@ -4915,6 +4910,28 @@ enabled \(see the `allout-passphrase-hint-handling' docstring for details), the hint string is stored in the local-variables section of the file, and solicited whenever the passphrase is changed." + (interactive "P") + (save-excursion + (allout-back-to-current-heading) + (allout-toggle-subtree-encryption) + ) + ) +;;;_ > allout-toggle-subtree-encryption (&optional fetch-pass) +(defun allout-toggle-subtree-encryption (&optional fetch-pass) + "Encrypt clear text or decrypt encoded topic contents \(body and subtopics.) + +Optional FETCH-PASS universal argument provokes key-pair encryption with +single universal argument. With doubled universal argument \(value = 16), +it forces prompting for the passphrase regardless of availability from the +passphrase cache. With no universal argument, the appropriate passphrase +is obtained from the cache, if available, else from the user. + +Currently only GnuPG encryption is supported. + +\**NOTE WELL** that the encrypted text must be ascii-armored. For gnupg +encryption, include the option ``armor'' in your ~/.gnupg/gpg.conf file. + +See `allout-toggle-current-subtree-encryption' for more details." (interactive "P") (save-excursion @@ -5022,6 +5039,9 @@ (require 'pgg) + (if (not (fboundp 'pgg-encrypt-symmetric)) + (error "Allout encryption depends on a newer version of pgg")) + (let* ((scheme (upcase (format "%s" (or pgg-scheme pgg-default-scheme "GPG")))) (for-key (and (equal key-type 'keypair) @@ -5498,7 +5518,7 @@ ;; we had to wait for this 'til now so prior topics are ;; encrypted, any relevant text shifts are in place: editing-point (marker-position current-mark))) - (allout-toggle-current-subtree-encryption) + (allout-toggle-subtree-encryption) (if (not was-modified) (set-buffer-modified-p nil)) ) diff -r 8e25aa911e3e -r 37d0562504bf lisp/buff-menu.el --- a/lisp/buff-menu.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/buff-menu.el Sat Dec 10 21:18:28 2005 +0000 @@ -89,6 +89,16 @@ :type 'number :group 'Buffer-menu) +(defcustom Buffer-menu-use-frame-buffer-list t + "If non-nil, the Buffer Menu uses the selected frame's buffer list. +Buffers that were never selected in that frame are listed at the end. +If the value is nil, the Buffer Menu uses the global buffer list. +This variable matters if the Buffer Menu is sorted by visited order, +as it is by default." + :type 'boolean + :group 'Buffer-menu + :version "22.1") + ;; This should get updated & resorted when you click on a column heading (defvar Buffer-menu-sort-column nil "*2 for sorting by buffer names. 5 for sorting by file names. @@ -722,7 +732,10 @@ (if (memq c '(?\n ?\s)) c underline)) header))))) ;; Collect info for every buffer we're interested in. - (dolist (buffer (or buffer-list (buffer-list (selected-frame)))) + (dolist (buffer (or buffer-list + (buffer-list + (when Buffer-menu-use-frame-buffer-list + (selected-frame))))) (with-current-buffer buffer (let ((name (buffer-name)) (file buffer-file-name)) diff -r 8e25aa911e3e -r 37d0562504bf lisp/completion.el --- a/lisp/completion.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/completion.el Sat Dec 10 21:18:28 2005 +0000 @@ -302,7 +302,8 @@ (cond ((file-readable-p olddef) olddef) ((file-directory-p (convert-standard-filename "~/.emacs.d/")) - (convert-standard-filename (expand-file-name completions "~/.emacs.d/"))) + (convert-standard-filename + (expand-file-name "completions" "~/.emacs.d/"))) (t olddef))) "The filename to save completions to." :type 'file diff -r 8e25aa911e3e -r 37d0562504bf lisp/cus-edit.el --- a/lisp/cus-edit.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/cus-edit.el Sat Dec 10 21:18:28 2005 +0000 @@ -975,13 +975,15 @@ ;;;###autoload (defun customize-group (group) "Customize GROUP, which must be a customization group." - (interactive (list (let ((completion-ignore-case t)) - (completing-read "Customize group (default emacs): " - obarray - (lambda (symbol) - (or (get symbol 'custom-loads) - (get symbol 'custom-group))) - t)))) + (interactive + (list (let ((completion-ignore-case t)) + (completing-read "Customize group (default emacs): " + obarray + (lambda (symbol) + (or (and (get symbol 'custom-loads) + (not (get symbol 'custom-autoload))) + (get symbol 'custom-group))) + t)))) (when (stringp group) (if (string-equal "" group) (setq group 'emacs) @@ -998,13 +1000,15 @@ ;;;###autoload (defun customize-group-other-window (group) "Customize GROUP, which must be a customization group." - (interactive (list (let ((completion-ignore-case t)) - (completing-read "Customize group (default emacs): " - obarray - (lambda (symbol) - (or (get symbol 'custom-loads) - (get symbol 'custom-group))) - t)))) + (interactive + (list (let ((completion-ignore-case t)) + (completing-read "Customize group (default emacs): " + obarray + (lambda (symbol) + (or (and (get symbol 'custom-loads) + (not (get symbol 'custom-autoload))) + (get symbol 'custom-group))) + t)))) (when (stringp group) (if (string-equal "" group) (setq group 'emacs) diff -r 8e25aa911e3e -r 37d0562504bf lisp/descr-text.el --- a/lisp/descr-text.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/descr-text.el Sat Dec 10 21:18:28 2005 +0000 @@ -464,6 +464,9 @@ (single-key-description char) (string-to-multibyte (char-to-string char))))) + (orig-buf (current-buffer)) + (help-buf (if (eq orig-buf (get-buffer "*Help*")) + "*Help-2*" "*Help*")) item-list max-width unicode) (if (or (< char 256) @@ -616,7 +619,7 @@ (setq max-width (apply #'max (mapcar #'(lambda (x) (if (cadr x) (length (car x)) 0)) item-list))) - (with-output-to-temp-buffer "*Help*" + (with-output-to-temp-buffer help-buf (with-current-buffer standard-output (set-buffer-multibyte multibyte-p) (let ((formatter (format "%%%ds:" max-width))) @@ -636,18 +639,17 @@ (insert " " clm))) (insert "\n")))) - (save-excursion - (goto-char (point-min)) - (re-search-forward "character:[ \t\n]+") - (setq pos (point))) - (let ((end (+ pos (length char-description)))) - (if overlays + (when overlays + (save-excursion + (goto-char (point-min)) + (re-search-forward "character:[ \t\n]+") + (let* ((end (+ (point) (length char-description)))) (mapc #'(lambda (props) - (let ((o (make-overlay pos end))) + (let ((o (make-overlay (point) end))) (while props (overlay-put o (car props) (nth 1 props)) (setq props (cddr props))))) - overlays))) + overlays)))) (when disp-vector (insert @@ -720,7 +722,9 @@ (insert "\nSee the variable `reference-point-alist' for " "the meaning of the rule.\n")) - (describe-text-properties pos (current-buffer)) + (save-excursion + (set-buffer orig-buf) + (describe-text-properties pos help-buf)) (describe-text-mode))))) (defalias 'describe-char-after 'describe-char) diff -r 8e25aa911e3e -r 37d0562504bf lisp/disp-table.el --- a/lisp/disp-table.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/disp-table.el Sat Dec 10 21:18:28 2005 +0000 @@ -222,7 +222,7 @@ (set-terminal-coding-system nil)))) (display-warning 'i18n - "`standard-display-european' is semi-obsolete" + "`standard-display-european' is semi-obsolete; see its doc string for details" :warning) ;; Switch to Latin-1 language environment diff -r 8e25aa911e3e -r 37d0562504bf lisp/emacs-lisp/autoload.el --- a/lisp/emacs-lisp/autoload.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/emacs-lisp/autoload.el Sat Dec 10 21:18:28 2005 +0000 @@ -86,10 +86,10 @@ ;; For special function-like operators, use the `autoload' function. ((memq car '(defun define-skeleton defmacro define-derived-mode - define-compilation-mode - define-generic-mode easy-mmode-define-minor-mode - easy-mmode-define-global-mode - define-minor-mode defun* defmacro*)) + define-compilation-mode define-generic-mode + easy-mmode-define-global-mode define-global-minor-mode + easy-mmode-define-minor-mode define-minor-mode + defun* defmacro*)) (let* ((macrop (memq car '(defmacro defmacro*))) (name (nth 1 form)) (args (case car @@ -109,6 +109,7 @@ (or (and (memq car '(define-skeleton define-derived-mode define-generic-mode easy-mmode-define-global-mode + define-global-minor-mode easy-mmode-define-minor-mode define-minor-mode)) t) (eq (car-safe (car body)) 'interactive)) diff -r 8e25aa911e3e -r 37d0562504bf lisp/emacs-lisp/derived.el --- a/lisp/emacs-lisp/derived.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/emacs-lisp/derived.el Sat Dec 10 21:18:28 2005 +0000 @@ -200,12 +200,19 @@ No problems result if this variable is not bound. `add-hook' automatically binds it. (This is true for all hook variables.)" name))) + (unless (boundp ',map) + (put ',map 'definition-name ',child)) (defvar ,map (make-sparse-keymap)) ,(if declare-syntax - `(defvar ,syntax (make-syntax-table))) + `(progn + (unless (boundp ',syntax) + (put ',syntax 'definition-name ',child)) + (defvar ,syntax (make-syntax-table)))) ,(if declare-abbrev - `(defvar ,abbrev - (progn (define-abbrev-table ',abbrev nil) ,abbrev))) + `(progn + (put ',abbrev 'definition-name ',child) + (defvar ,abbrev + (progn (define-abbrev-table ',abbrev nil) ,abbrev)))) (put ',child 'derived-mode-parent ',parent) ,(if group `(put ',child 'custom-mode-group ,group)) diff -r 8e25aa911e3e -r 37d0562504bf lisp/emacs-lisp/easy-mmode.el --- a/lisp/emacs-lisp/easy-mmode.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/emacs-lisp/easy-mmode.el Sat Dec 10 21:18:28 2005 +0000 @@ -515,6 +515,7 @@ (unless (pos-visible-in-window-p endpt nil t) (recenter '(0)))))) ,re-narrow-maybe))) + (put ',next-sym 'definition-name ',base) (defun ,prev-sym (&optional count) ,(format "Go to the previous COUNT'th %s" (or name base-name)) (interactive) @@ -524,7 +525,8 @@ ,check-narrow-maybe (unless (re-search-backward ,re nil t count) (error "No previous %s" ,name)) - ,re-narrow-maybe)))))) + ,re-narrow-maybe))) + (put ',prev-sym 'definition-name ',base)))) (provide 'easy-mmode) diff -r 8e25aa911e3e -r 37d0562504bf lisp/emacs-lisp/edebug.el --- a/lisp/emacs-lisp/edebug.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/emacs-lisp/edebug.el Sat Dec 10 21:18:28 2005 +0000 @@ -733,8 +733,7 @@ ;; Leave point before the next token, skipping white space and comments. (skip-chars-forward " \t\r\n\f") (while (= (following-char) ?\;) - ;; \r is counted as a comment terminator to support selective display. - (skip-chars-forward "^\n\r") ; skip the comment + (skip-chars-forward "^\n") ; skip the comment (skip-chars-forward " \t\r\n\f"))) diff -r 8e25aa911e3e -r 37d0562504bf lisp/emacs-lisp/find-func.el --- a/lisp/emacs-lisp/find-func.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/emacs-lisp/find-func.el Sat Dec 10 21:18:28 2005 +0000 @@ -63,8 +63,9 @@ ;; (define-derived-mode foo ...), (define-minor-mode foo) (concat "^\\s-*(\\(def\\(ine-skeleton\\|ine-generic-mode\\|ine-derived-mode\\|\ -ine-minor-mode\\|ine-compilation-mode\\|un-cvs-mode\\|foo\\|[^cfgv]\\w+\\*?\\)\ -\\|easy-mmode-define-global-mode\\|menu-bar-make-toggle\\)" +ine\\(?:-global\\)?-minor-mode\\|ine-compilation-mode\\|un-cvs-mode\\|\ +foo\\|[^cfgv]\\w+\\*?\\)\\|easy-mmode-define-[a-z-]+\\|easy-menu-define\\|\ +menu-bar-make-toggle\\)" find-function-space-re "\\('\\|\(quote \\)?%s\\(\\s-\\|$\\|\(\\|\)\\)") "The regexp used by `find-function' to search for a function definition. @@ -78,7 +79,11 @@ :version "21.1") (defcustom find-variable-regexp - (concat"^\\s-*(def[^fumag]\\(\\w\\|\\s_\\)+\\*?" find-function-space-re "%s\\(\\s-\\|$\\)") + (concat + "^\\s-*(\\(def[^fumag]\\(\\w\\|\\s_\\)+\\*?\\|\ +easy-mmode-def\\(map\\|syntax\\)\\|easy-menu-define\\)" + find-function-space-re + "%s\\(\\s-\\|$\\)") "The regexp used by `find-variable' to search for a variable definition. Note it must contain a `%s' at the place where `format' should insert the variable name. The default value diff -r 8e25aa911e3e -r 37d0562504bf lisp/emacs-lisp/lisp-mode.el --- a/lisp/emacs-lisp/lisp-mode.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/emacs-lisp/lisp-mode.el Sat Dec 10 21:18:28 2005 +0000 @@ -96,13 +96,13 @@ (regexp-opt '("defun" "defun*" "defsubst" "defmacro" "defadvice" "define-skeleton" - "define-minor-mode" "define-derived-mode" - "define-generic-mode" + "define-minor-mode" "define-global-minor-mode" + "define-derived-mode" "define-generic-mode" "define-compiler-macro" "define-modify-macro" "defsetf" "define-setf-expander" "define-method-combination" "defgeneric" "defmethod") t)) - "\\s-+\\(\\sw\\(\\sw\\|\\s_\\)+\\)")) + "\\s-+\\(\\(\\sw\\|\\s_\\)+\\)")) 2) (list (purecopy "Variables") (purecopy (concat "^\\s-*(" @@ -110,7 +110,7 @@ (regexp-opt '("defvar" "defconst" "defconstant" "defcustom" "defparameter" "define-symbol-macro") t)) - "\\s-+\\(\\sw\\(\\sw\\|\\s_\\)+\\)")) + "\\s-+\\(\\(\\sw\\|\\s_\\)+\\)")) 2) (list (purecopy "Types") (purecopy (concat "^\\s-*(" @@ -119,7 +119,7 @@ '("defgroup" "deftheme" "deftype" "defstruct" "defclass" "define-condition" "define-widget" "defface" "defpackage") t)) - "\\s-+'?\\(\\sw\\(\\sw\\|\\s_\\)+\\)")) + "\\s-+'?\\(\\(\\sw\\|\\s_\\)+\\)")) 2)) "Imenu generic expression for Lisp mode. See `imenu-generic-expression'.") @@ -141,6 +141,8 @@ (put 'define-compilation-mode 'doc-string-elt 3) (put 'easy-mmode-define-minor-mode 'doc-string-elt 2) (put 'define-minor-mode 'doc-string-elt 2) +(put 'easy-mmode-define-global-mode 'doc-string-elt 2) +(put 'define-global-minor-mode 'doc-string-elt 2) (put 'define-generic-mode 'doc-string-elt 7) (put 'define-ibuffer-filter 'doc-string-elt 2) (put 'define-ibuffer-op 'doc-string-elt 3) diff -r 8e25aa911e3e -r 37d0562504bf lisp/files.el --- a/lisp/files.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/files.el Sat Dec 10 21:18:28 2005 +0000 @@ -1869,7 +1869,6 @@ ;; /tmp/Re.... or Message ("\\`/tmp/Re" . text-mode) ("/Message[0-9]*\\'" . text-mode) - ("/drafts/[0-9]+\\'" . mh-letter-mode) ("\\.zone\\'" . zone-mode) ;; some news reader is reported to use this ("\\`/tmp/fol/" . text-mode) diff -r 8e25aa911e3e -r 37d0562504bf lisp/font-core.el --- a/lisp/font-core.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/font-core.el Sat Dec 10 21:18:28 2005 +0000 @@ -146,7 +146,7 @@ The above is the default behavior of `font-lock-mode'; you may specify your own function which is called when `font-lock-mode' is toggled via `font-lock-function'. " - :group 'font-lock + nil nil nil ;; Don't turn on Font Lock mode if we don't have a display (we're running a ;; batch job) or if the buffer is invisible (the name starts with a space). (when (or noninteractive (eq (aref (buffer-name) 0) ?\ )) @@ -291,12 +291,13 @@ (let (inhibit-quit) (turn-on-font-lock)))) -(easy-mmode-define-global-mode - global-font-lock-mode font-lock-mode turn-on-font-lock-if-enabled - :extra-args (dummy) - :initialize 'custom-initialize-safe-default - :init-value (not (or noninteractive emacs-basic-display)) - :version "22.1") +(define-global-minor-mode global-font-lock-mode + font-lock-mode turn-on-font-lock-if-enabled + :extra-args (dummy) + :initialize 'custom-initialize-safe-default + :init-value (not (or noninteractive emacs-basic-display)) + :group 'font-lock + :version "22.1") ;;; End of Global Font Lock mode. diff -r 8e25aa911e3e -r 37d0562504bf lisp/font-lock.el --- a/lisp/font-lock.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/font-lock.el Sat Dec 10 21:18:28 2005 +0000 @@ -1967,7 +1967,8 @@ ;; Function declarations. "\\(advice\\|varalias\\|alias\\|generic\\|macro\\*?\\|method\\|" "setf\\|subst\\*?\\|un\\*?\\|" - "ine-\\(condition\\|\\(?:derived\\|minor\\|generic\\)-mode\\|" + "ine-\\(condition\\|" + "\\(?:derived\\|\\(?:global-\\)?minor\\|generic\\)-mode\\|" "method-combination\\|setf-expander\\|skeleton\\|widget\\|" "function\\|\\(compiler\\|modify\\|symbol\\)-macro\\)\\)\\|" ;; Variable declarations. diff -r 8e25aa911e3e -r 37d0562504bf lisp/frame.el --- a/lisp/frame.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/frame.el Sat Dec 10 21:18:28 2005 +0000 @@ -953,6 +953,9 @@ (run-hooks 'after-setting-font-hook 'after-setting-font-hooks)) (defun set-frame-parameter (frame parameter value) + "Set frame parameter PARAMETER to VALUE on FRAME. +If FRAME is nil, it defaults to the selected frame. +See `modify-frame-parameters.'" (modify-frame-parameters frame (list (cons parameter value)))) (defun set-background-color (color-name) diff -r 8e25aa911e3e -r 37d0562504bf lisp/help.el --- a/lisp/help.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/help.el Sat Dec 10 21:18:28 2005 +0000 @@ -111,7 +111,8 @@ (defvar help-return-method nil "What to do to \"exit\" the help buffer. This is a list - (WINDOW . t) delete the selected window, go to WINDOW. + (WINDOW . t) delete the selected window (and possibly its frame, + see `quit-window' and `View-quit'), go to WINDOW. (WINDOW . quit-window) do quit-window, then select WINDOW. (WINDOW BUF START POINT) display BUF at START, POINT, then select WINDOW.") @@ -119,10 +120,14 @@ "Display or return message saying how to restore windows after help command. This function assumes that `standard-output' is the help buffer. It computes a message, and applies the optional argument FUNCTION to it. -If FUNCTION is nil, it applies `message', thus displaying the message." +If FUNCTION is nil, it applies `message', thus displaying the message. +In addition, this function sets up `help-return-method', which see, that +specifies what to do when the user exits the help buffer." (and (not (get-buffer-window standard-output)) (let ((first-message - (cond ((special-display-p (buffer-name standard-output)) + (cond ((or + pop-up-frames + (special-display-p (buffer-name standard-output))) (setq help-return-method (cons (selected-window) t)) ;; If the help output buffer is a special display buffer, ;; don't say anything about how to get rid of it. @@ -154,7 +159,8 @@ (if first-message " ") ;; If the help buffer will go in a separate frame, ;; it's no use mentioning a command to scroll, so don't. - (if (special-display-p (buffer-name standard-output)) + (if (or pop-up-windows + (special-display-p (buffer-name standard-output))) nil (if (same-window-p (buffer-name standard-output)) ;; Say how to scroll this window. diff -r 8e25aa911e3e -r 37d0562504bf lisp/ido.el --- a/lisp/ido.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/ido.el Sat Dec 10 21:18:28 2005 +0000 @@ -252,7 +252,7 @@ ;; ;;(defun ido-my-keys () ;; "Add my keybindings for ido." -;; (define-key ido-mode-map " " 'ido-next-match) +;; (define-key ido-completion-map " " 'ido-next-match) ;; ) ;; Seeing all the matching buffers or files @@ -716,7 +716,7 @@ "*Hook run after the ido variables and keymap have been setup. The dynamic variable `ido-cur-item' contains the current type of item that is read by ido, possible values are file, dir, buffer, and list. -Additional keys can be defined in `ido-mode-map'." +Additional keys can be defined in `ido-completion-map'." :type 'hook :group 'ido) @@ -898,19 +898,19 @@ ;; Persistent variables -(defvar ido-mode-map nil +(defvar ido-completion-map nil "Currently active keymap for ido commands.") -(defvar ido-mode-common-map nil +(defvar ido-common-completion-map nil "Keymap for all ido commands.") -(defvar ido-mode-file-map nil +(defvar ido-file-completion-map nil "Keymap for ido file commands.") -(defvar ido-mode-file-dir-map nil +(defvar ido-file-dir-completion-map nil "Keymap for ido file and directory commands.") -(defvar ido-mode-buffer-map nil +(defvar ido-buffer-completion-map nil "Keymap for ido buffer commands.") (defvar ido-file-history nil @@ -1345,7 +1345,7 @@ (ido-everywhere (if ido-everywhere 1 -1)) (when ido-mode - (ido-init-mode-maps)) + (ido-init-completion-maps)) (when ido-mode (add-hook 'minibuffer-setup-hook 'ido-minibuffer-setup) @@ -1354,12 +1354,7 @@ (add-hook 'kill-emacs-hook 'ido-kill-emacs-hook) - (if ido-minor-mode-map-entry - (setcdr ido-minor-mode-map-entry (make-sparse-keymap)) - (setq ido-minor-mode-map-entry (cons 'ido-mode (make-sparse-keymap))) - (add-to-list 'minor-mode-map-alist ido-minor-mode-map-entry)) - - (let ((map (cdr ido-minor-mode-map-entry))) + (let ((map (make-sparse-keymap))) (when (memq ido-mode '(file both)) (define-key map [remap find-file] 'ido-find-file) (define-key map [remap find-file-read-only] 'ido-find-file-read-only) @@ -1379,7 +1374,13 @@ (define-key map [remap switch-to-buffer-other-frame] 'ido-switch-buffer-other-frame) (define-key map [remap insert-buffer] 'ido-insert-buffer) (define-key map [remap kill-buffer] 'ido-kill-buffer) - (define-key map [remap display-buffer] 'ido-display-buffer))))) + (define-key map [remap display-buffer] 'ido-display-buffer)) + + (if ido-minor-mode-map-entry + (setcdr ido-minor-mode-map-entry map) + (setq ido-minor-mode-map-entry (cons 'ido-mode map)) + (add-to-list 'minor-mode-map-alist ido-minor-mode-map-entry))))) + (defun ido-everywhere (arg) "Toggle using ido speed-ups everywhere file and directory names are read. @@ -1404,8 +1405,8 @@ ;;; IDO KEYMAP -(defun ido-init-mode-maps () - "Set up the keymaps used by `ido'." +(defun ido-init-completion-maps () + "Set up the completion keymaps used by `ido'." ;; Common map (let ((map (make-sparse-keymap))) @@ -1431,7 +1432,7 @@ (define-key map "\C-f" 'ido-magic-forward-char) (define-key map "\C-d" 'ido-magic-delete-char) (set-keymap-parent map minibuffer-local-map) - (setq ido-mode-common-map map)) + (setq ido-common-completion-map map)) ;; File and directory map (let ((map (make-sparse-keymap))) @@ -1457,8 +1458,8 @@ (define-key map [(meta control ?o)] 'ido-next-work-file) (define-key map [(meta ?p)] 'ido-prev-work-directory) (define-key map [(meta ?s)] 'ido-merge-work-directories) - (set-keymap-parent map ido-mode-common-map) - (setq ido-mode-file-dir-map map)) + (set-keymap-parent map ido-common-completion-map) + (setq ido-file-dir-completion-map map)) ;; File only map (let ((map (make-sparse-keymap))) @@ -1467,19 +1468,19 @@ (define-key map "\C-w" 'ido-copy-current-file-name) (define-key map [(meta ?l)] 'ido-toggle-literal) (define-key map "\C-v" 'ido-toggle-vc) - (set-keymap-parent map ido-mode-file-dir-map) - (setq ido-mode-file-map map)) + (set-keymap-parent map ido-file-dir-completion-map) + (setq ido-file-completion-map map)) ;; Buffer map (let ((map (make-sparse-keymap))) (define-key map "\C-x\C-f" 'ido-enter-find-file) (define-key map "\C-x\C-b" 'ido-fallback-command) (define-key map "\C-k" 'ido-kill-buffer-at-head) - (set-keymap-parent map ido-mode-common-map) - (setq ido-mode-buffer-map map))) - - -(defun ido-define-mode-map () + (set-keymap-parent map ido-common-completion-map) + (setq ido-buffer-completion-map map))) + + +(defun ido-setup-completion-map () "Set up the keymap for `ido'." ;; generated every time so that it can inherit new functions. @@ -1500,18 +1501,18 @@ (define-key map [remap viper-delete-backward-word] 'ido-delete-backward-word-updir)) (set-keymap-parent map (if (eq ido-cur-item 'file) - ido-mode-file-map - ido-mode-file-dir-map))) + ido-file-completion-map + ido-file-dir-completion-map))) ((eq ido-cur-item 'buffer) (when ido-context-switch-command (define-key map "\C-x\C-f" ido-context-switch-command)) - (set-keymap-parent map ido-mode-buffer-map)) + (set-keymap-parent map ido-buffer-completion-map)) (t - (set-keymap-parent map ido-mode-common-map))) - - (setq ido-mode-map map))) + (set-keymap-parent map ido-common-completion-map))) + + (setq ido-completion-map map))) (defun ido-final-slash (dir &optional fix-it) ;; return DIR if DIR has final slash. @@ -1683,7 +1684,7 @@ (ido-enable-regexp ido-enable-regexp) ) - (ido-define-mode-map) + (ido-setup-completion-map) (setq ido-text-init initial) (setq ido-input-stack nil) @@ -1788,7 +1789,8 @@ (if (and ido-matches (eq ido-try-merged-list 'auto)) (setq ido-try-merged-list t)) (let - ((minibuffer-local-completion-map ido-mode-map) + ((minibuffer-local-completion-map ido-completion-map) + (minibuffer-local-filename-completion-map ido-completion-map) (max-mini-window-height (or ido-max-window-height (and (boundp 'max-mini-window-height) max-mini-window-height))) (ido-completing-read t) @@ -3670,7 +3672,7 @@ displayed if substring-matching is used \(default). Look at `ido-enable-prefix' and `ido-toggle-prefix'. When you have found the buffer you want, it can then be selected. As you type, most keys have -their normal keybindings, except for the following: \\ +their normal keybindings, except for the following: \\ RET Select the buffer at the front of the list of matches. If the list is empty, possibly prompt to create new buffer. @@ -3758,7 +3760,7 @@ if substring-matching is used \(default). Look at `ido-enable-prefix' and `ido-toggle-prefix'. When you have found the filename you want, it can then be selected. As you type, most keys have their normal keybindings, -except for the following: \\ +except for the following: \\ RET Select the file at the front of the list of matches. If the list is empty, possibly prompt to create new file. diff -r 8e25aa911e3e -r 37d0562504bf lisp/info.el --- a/lisp/info.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/info.el Sat Dec 10 21:18:28 2005 +0000 @@ -3181,11 +3181,11 @@ (if (display-graphic-p) (let ((map (make-sparse-keymap))) (tool-bar-local-item-from-menu 'Info-exit "close" map Info-mode-map) + (tool-bar-local-item-from-menu 'Info-history-back "left-arrow" map Info-mode-map) + (tool-bar-local-item-from-menu 'Info-history-forward "right-arrow" map Info-mode-map) (tool-bar-local-item-from-menu 'Info-prev "prev-node" map Info-mode-map) (tool-bar-local-item-from-menu 'Info-next "next-node" map Info-mode-map) (tool-bar-local-item-from-menu 'Info-up "up-node" map Info-mode-map) - (tool-bar-local-item-from-menu 'Info-history-back "left-arrow" map Info-mode-map) - (tool-bar-local-item-from-menu 'Info-history-forward "right-arrow" map Info-mode-map) (tool-bar-local-item-from-menu 'Info-top-node "home" map Info-mode-map) (tool-bar-local-item-from-menu 'Info-index "index" map Info-mode-map) (tool-bar-local-item-from-menu 'Info-goto-node "jump-to" map Info-mode-map) @@ -3800,17 +3800,25 @@ (and (not (equal (match-string 4) "")) (match-string 4)) (match-string 2))))) - (file Info-current-file) + (external-link-p + (string-match "(\\([^)]+\\))\\([^)]*\\)" node)) + (file (if external-link-p + (file-name-nondirectory + (match-string 1 node)) + Info-current-file)) (hl Info-history-list) res) - (if (string-match "(\\([^)]+\\))\\([^)]*\\)" node) - (setq file (Info-find-file (match-string 1 node) t) - node (if (equal (match-string 2 node) "") + (if external-link-p + (setq node (if (equal (match-string 2 node) "") "Top" (match-string 2 node)))) (while hl (if (and (string-equal node (nth 1 (car hl))) - (string-equal file (nth 0 (car hl)))) + (string-equal + file (if external-link-p + (file-name-nondirectory + (caar hl)) + (caar hl)))) (setq res (car hl) hl nil) (setq hl (cdr hl)))) res))) 'info-xref-visited 'info-xref)) @@ -3902,20 +3910,27 @@ ;; Display visited menu items in a different face (if (and Info-fontify-visited-nodes (save-match-data - (let ((node (if (equal (match-string 3) "") - (match-string 1) - (match-string 3))) - (file Info-current-file) - (hl Info-history-list) - res) - (if (string-match "(\\([^)]+\\))\\([^)]*\\)" node) - (setq file (Info-find-file (match-string 1 node) t) - node (if (equal (match-string 2 node) "") + (let* ((node (if (equal (match-string 3) "") + (match-string 1) + (match-string 3))) + (external-link-p + (string-match "(\\([^)]+\\))\\([^)]*\\)" node)) + (file (if external-link-p + (file-name-nondirectory + (match-string 1 node)) + Info-current-file)) + (hl Info-history-list) + res) + (if external-link-p + (setq node (if (equal (match-string 2 node) "") "Top" (match-string 2 node)))) (while hl (if (and (string-equal node (nth 1 (car hl))) - (string-equal file (nth 0 (car hl)))) + (string-equal + file (if external-link-p + (file-name-nondirectory (caar hl)) + (caar hl)))) (setq res (car hl) hl nil) (setq hl (cdr hl)))) res))) 'info-xref-visited 'info-xref))) diff -r 8e25aa911e3e -r 37d0562504bf lisp/international/kinsoku.el --- a/lisp/international/kinsoku.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/international/kinsoku.el Sat Dec 10 21:18:28 2005 +0000 @@ -109,7 +109,7 @@ $A!.!0#"#(!2!4!6!8!:!!c!d!e#@!f!l(B" ;; Chinese GB2312 "$A(E(F(G(H(I(J(K(L(M(N(O(P(Q(R(S(T(U(V(W(X(Y(h(B\ -$(0!>!@!B!D!F!H!J!L!N!P!R!T!V!X!Z!\!^!`!b(B" +\$(0!>!@!B!D!F!H!J!L!N!P!R!T!V!X!Z!\!^!`!b(B" ;; Chinese BIG5 "$(0!d!f!h!j!k!q!p"i"j"k"n"x$u$v$w$x$y$z${(B\ $(0$|$}$~%!%"%#%$%%%&%'%(%)%*%+%:(B")) @@ -126,7 +126,7 @@ (let ((pos-and-column (save-excursion (forward-char 1) - (while (and (not (eobp)) + (while (and (not (eolp)) (or (aref (char-category-set (following-char)) ?>) ;; protect non-kinsoku words (not (or (eq (preceding-char) ? ) diff -r 8e25aa911e3e -r 37d0562504bf lisp/international/latexenc.el --- a/lisp/international/latexenc.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/international/latexenc.el Sat Dec 10 21:18:28 2005 +0000 @@ -78,7 +78,7 @@ ("next" . next) ; The Next encoding ("utf8" . utf-8) ("utf8x" . utf-8)) ; used by the Unicode LaTeX package - "Mapping from LaTeX encodings to Emacs coding systems. + "Mapping from LaTeX encodings in \"inputenc.sty\" to Emacs coding systems. LaTeX encodings are specified with \"\\usepackage[encoding]{inputenc}\". Used by the function `latexenc-find-file-coding-system'." :group 'files diff -r 8e25aa911e3e -r 37d0562504bf lisp/international/mule-cmds.el --- a/lisp/international/mule-cmds.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/international/mule-cmds.el Sat Dec 10 21:18:28 2005 +0000 @@ -1126,6 +1126,13 @@ see `language-info-alist'." (if (symbolp lang-env) (setq lang-env (symbol-name lang-env))) + (set-language-info-internal lang-env key info) + (if (equal lang-env current-language-environment) + (set-language-environment lang-env))) + +(defun set-language-info-internal (lang-env key info) + "Internal use only. +Arguments are the same as `set-language-info'." (let (lang-slot key-slot) (setq lang-slot (assoc lang-env language-info-alist)) (if (null lang-slot) ; If no slot for the language, add it. @@ -1196,9 +1203,11 @@ (define-key-after setup-map (vector (intern lang-env)) (cons lang-env 'setup-specified-language-environment) t) - (while alist - (set-language-info lang-env (car (car alist)) (cdr (car alist))) - (setq alist (cdr alist))))) + (dolist (elt alist) + (set-language-info-internal lang-env (car elt) (cdr elt))) + + (if (equal lang-env current-language-environment) + (set-language-environment lang-env)))) (defun read-language-name (key prompt &optional default) "Read a language environment name which has information for KEY. @@ -1789,7 +1798,9 @@ (defun set-display-table-and-terminal-coding-system (language-name &optional coding-system display) "Set up the display table and terminal coding system for LANGUAGE-NAME." (let ((coding (get-language-info language-name 'unibyte-display))) - (if coding + (if (and coding + (or (not coding-system) + (coding-system-equal coding coding-system))) (standard-display-european-internal) ;; The following 2 lines undo the 8-bit display that we set up ;; in standard-display-european-internal, which see. This is in @@ -2129,7 +2140,7 @@ ;; That's actually what the GNU locales define, modulo things like ;; en_IN -- fx. ("en_IN" "English" utf-8) ; glibc uses utf-8 for English in India - ("en" . "Latin-1") ; English + ("en" "English" iso-8859-1) ; English ("eo" . "Latin-3") ; Esperanto ("es" "Spanish" iso-8859-1) ("et" . "Latin-1") ; Estonian diff -r 8e25aa911e3e -r 37d0562504bf lisp/log-view.el --- a/lisp/log-view.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/log-view.el Sat Dec 10 21:18:28 2005 +0000 @@ -196,9 +196,9 @@ (defun log-view-diff (beg end) "Get the diff for several revisions. -If the point is the same as the mark, get the diff for this revision. -Otherwise, get the diff between the revisions -were the region starts and ends." +If the point is the same as the mark or the mark is not active, +get the diff for this revision. Otherwise, get the diff between +the revisions where the region starts and ends." (interactive (list (if mark-active (region-beginning) (point)) (if mark-active (region-end) (point)))) diff -r 8e25aa911e3e -r 37d0562504bf lisp/mail/sendmail.el --- a/lisp/mail/sendmail.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mail/sendmail.el Sat Dec 10 21:18:28 2005 +0000 @@ -49,8 +49,8 @@ :version "22.1") ;;;###autoload -(defcustom mail-from-style 'angles "\ -*Specifies how \"From:\" fields look. +(defcustom mail-from-style 'angles + "Specifies how \"From:\" fields look. If `nil', they contain just the return address like: king@grassland.com @@ -72,7 +72,7 @@ ;;;###autoload (defcustom mail-specify-envelope-from nil - "*If non-nil, specify the envelope-from address when sending mail. + "If non-nil, specify the envelope-from address when sending mail. The value used to specify it is whatever is found in the variable `mail-envelope-from', with `user-mail-address' as fallback. @@ -85,7 +85,7 @@ :group 'sendmail) (defcustom mail-envelope-from nil - "*If non-nil, designate the envelope-from address when sending mail. + "If non-nil, designate the envelope-from address when sending mail. This only has an effect if `mail-specify-envelope-from' is non-nil. The value should be either a string, or the symbol `header' (in which case the contents of the \"From\" header of the message @@ -98,29 +98,34 @@ :group 'sendmail) ;;;###autoload -(defcustom mail-self-blind nil "\ -*Non-nil means insert BCC to self in messages to be sent. +(defcustom mail-self-blind nil + "Non-nil means insert BCC to self in messages to be sent. This is done when the message is initialized, so you can remove or alter the BCC field to override the default." :type 'boolean :group 'sendmail) ;;;###autoload -(defcustom mail-interactive nil "\ -*Non-nil means when sending a message wait for and display errors. +(defcustom mail-interactive nil + "Non-nil means when sending a message wait for and display errors. nil means let mailer mail back a message to report errors." :type 'boolean :group 'sendmail) -;;;###autoload -(defcustom mail-yank-ignored-headers "^via:\\|^mail-from:\\|^origin:\\|^status:\\|^remailed\\|^received:\\|^message-id:\\|^summary-line:\\|^to:\\|^subject:\\|^in-reply-to:\\|^return-path:\\|^mail-reply-to:\\|^mail-followup-to:" "\ -*Delete these headers from old message when it's inserted in a reply." +(defcustom mail-yank-ignored-headers + (concat "^" + (regexp-opt '("via" "mail-from" "origin" "status" "remailed" + "received" "message-id" "summary-line" "to" "subject" + "in-reply-to" "return-path" "mail-reply-to" + "mail-followup-to") "\\(?:") + ":") + "Delete these headers from old message when it's inserted in a reply." :type 'regexp :group 'sendmail) ;; Useful to set in site-init.el ;;;###autoload -(defcustom send-mail-function +(defcustom send-mail-function (if (and window-system (memq system-type '(darwin windows-nt))) 'mailclient-send-it 'sendmail-send-it) @@ -138,30 +143,30 @@ :group 'sendmail) ;;;###autoload -(defcustom mail-header-separator "--text follows this line--" "\ -*Line used to separate headers from text in messages being composed." +(defcustom mail-header-separator "--text follows this line--" + "Line used to separate headers from text in messages being composed." :type 'string :group 'sendmail) ;; Set up mail-header-separator for use as a category text property. (put 'mail-header-separator 'rear-nonsticky '(category)) -;;; This was a nice idea, for preventing accidental modification of -;;; the separator. But I found it also prevented or obstructed -;;; certain deliberate operations, such as copying the separator line -;;; up to the top to send myself a copy of an already sent outgoing message -;;; and other things. So I turned it off. --rms. -;;;(put 'mail-header-separator 'read-only t) +;; This was a nice idea, for preventing accidental modification of +;; the separator. But I found it also prevented or obstructed +;; certain deliberate operations, such as copying the separator line +;; up to the top to send myself a copy of an already sent outgoing message +;; and other things. So I turned it off. --rms. +;;(put 'mail-header-separator 'read-only t) ;;;###autoload -(defcustom mail-archive-file-name nil "\ -*Name of file to write all outgoing messages in, or nil for none. +(defcustom mail-archive-file-name nil + "Name of file to write all outgoing messages in, or nil for none. This can be an inbox file or an Rmail file." :type '(choice file (const nil)) :group 'sendmail) ;;;###autoload (defcustom mail-default-reply-to nil - "*Address to insert as default Reply-to field of outgoing messages. + "Address to insert as default Reply-to field of outgoing messages. If nil, it will be initialized from the REPLYTO environment variable when you first send mail." :type '(choice (const nil) string) @@ -169,7 +174,7 @@ ;;;###autoload (defcustom mail-alias-file nil - "*If non-nil, the name of a file to use instead of `/usr/lib/aliases'. + "If non-nil, the name of a file to use instead of `/usr/lib/aliases'. This file defines aliases to be expanded by the mailer; this is a different feature from that of defining aliases in `.mailrc' to be expanded in Emacs. This variable has no effect unless your system uses sendmail as its mailer." @@ -178,7 +183,7 @@ ;;;###autoload (defcustom mail-personal-alias-file "~/.mailrc" - "*If non-nil, the name of the user's personal mail alias file. + "If non-nil, the name of the user's personal mail alias file. This file typically should be in same format as the `.mailrc' file used by the `Mail' or `mailx' program. This file need not actually exist." @@ -207,14 +212,14 @@ ;;;###autoload (defcustom mail-yank-prefix nil - "*Prefix insert on lines of yanked message being replied to. + "Prefix insert on lines of yanked message being replied to. nil means use indentation." :type '(choice (const nil) string) :group 'sendmail) ;;;###autoload (defcustom mail-indentation-spaces 3 - "*Number of spaces to insert at the beginning of each cited line. + "Number of spaces to insert at the beginning of each cited line. Used by `mail-yank-original' via `mail-indent-citation'." :type 'integer :group 'sendmail) @@ -230,7 +235,7 @@ ;;;###autoload (defcustom mail-citation-hook nil - "*Hook for modifying a citation just inserted in the mail buffer. + "Hook for modifying a citation just inserted in the mail buffer. Each hook function can find the citation between (point) and (mark t), and should leave point and mark around the citation text as modified. The hook functions can find the header of the cited message @@ -249,7 +254,7 @@ ;;;###autoload (defcustom mail-citation-prefix-regexp "[ \t]*[-a-z0-9A-Z]*>+[ \t]*\\|[ \t]*" - "*Regular expression to match a citation prefix plus whitespace. + "Regular expression to match a citation prefix plus whitespace. It should match whatever sort of citation prefixes you want to handle, with whitespace before and after; it should also match just whitespace. The default value matches citations like `foo-bar>' plus whitespace." @@ -258,7 +263,90 @@ :version "20.3") (defvar mail-abbrevs-loaded nil) -(defvar mail-mode-map nil) +(defvar mail-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "\M-\t" 'mail-complete) + (define-key map "\C-c?" 'describe-mode) + (define-key map "\C-c\C-f\C-t" 'mail-to) + (define-key map "\C-c\C-f\C-b" 'mail-bcc) + (define-key map "\C-c\C-f\C-f" 'mail-fcc) + (define-key map "\C-c\C-f\C-c" 'mail-cc) + (define-key map "\C-c\C-f\C-s" 'mail-subject) + (define-key map "\C-c\C-f\C-r" 'mail-reply-to) + (define-key map "\C-c\C-f\C-a" 'mail-mail-reply-to) ; author + (define-key map "\C-c\C-f\C-l" 'mail-mail-followup-to) ; list + (define-key map "\C-c\C-t" 'mail-text) + (define-key map "\C-c\C-y" 'mail-yank-original) + (define-key map "\C-c\C-r" 'mail-yank-region) + (define-key map [remap split-line] 'mail-split-line) + (define-key map "\C-c\C-q" 'mail-fill-yanked-message) + (define-key map "\C-c\C-w" 'mail-signature) + (define-key map "\C-c\C-v" 'mail-sent-via) + (define-key map "\C-c\C-c" 'mail-send-and-exit) + (define-key map "\C-c\C-s" 'mail-send) + (define-key map "\C-c\C-i" 'mail-attach-file) + + (define-key map [menu-bar mail] + (cons "Mail" (make-sparse-keymap "Mail"))) + + (define-key map [menu-bar mail fill] + '("Fill Citation" . mail-fill-yanked-message)) + + (define-key map [menu-bar mail yank] + '("Cite Original" . mail-yank-original)) + + (define-key map [menu-bar mail signature] + '("Insert Signature" . mail-signature)) + + (define-key map [menu-bar mail mail-sep] + '("--")) + + (define-key map [menu-bar mail cancel] + '("Cancel" . mail-dont-send)) + + (define-key map [menu-bar mail send-stay] + '("Send, Keep Editing" . mail-send)) + + (define-key map [menu-bar mail send] + '("Send Message" . mail-send-and-exit)) + + (define-key map [menu-bar headers] + (cons "Headers" (make-sparse-keymap "Move to Header"))) + + (define-key map [menu-bar headers text] + '("Text" . mail-text)) + + (define-key map [menu-bar headers expand-aliases] + '("Expand Aliases" . expand-mail-aliases)) + + (define-key map [menu-bar headers sent-via] + '("Sent Via" . mail-sent-via)) + + (define-key map [menu-bar headers mail-reply-to] + '("Mail Reply To" . mail-mail-reply-to)) + + (define-key map [menu-bar headers mail-followup-to] + '("Mail Followup To" . mail-mail-followup-to)) + + (define-key map [menu-bar headers reply-to] + '("Reply-To" . mail-reply-to)) + + (define-key map [menu-bar headers bcc] + '("Bcc" . mail-bcc)) + + (define-key map [menu-bar headers fcc] + '("Fcc" . mail-fcc)) + + (define-key map [menu-bar headers cc] + '("Cc" . mail-cc)) + + (define-key map [menu-bar headers subject] + '("Subject" . mail-subject)) + + (define-key map [menu-bar headers to] + '("To" . mail-to)) + + map)) (autoload 'build-mail-aliases "mailalias" "Read mail aliases from user's personal aliases file and set `mail-aliases'." @@ -273,7 +361,7 @@ ;;;###autoload (defcustom mail-signature nil - "*Text inserted at end of mail buffer when a message is initialized. + "Text inserted at end of mail buffer when a message is initialized. If t, it means to insert the contents of the file `mail-signature-file'. If a string, that string is inserted. (To make a proper signature, the string should begin with \\n\\n-- \\n, @@ -289,13 +377,13 @@ ;;;###autoload (defcustom mail-signature-file "~/.signature" - "*File containing the text inserted at end of mail buffer." + "File containing the text inserted at end of mail buffer." :type 'file :group 'sendmail) ;;;###autoload (defcustom mail-default-directory "~/" - "*Directory for mail buffers. + "Directory for mail buffers. Value of `default-directory' for mail buffers. This directory is used for auto-save files of mail buffers." :type '(directory :tag "Directory") @@ -310,7 +398,7 @@ ;;;###autoload (defcustom mail-default-headers nil - "*A string containing header lines, to be inserted in outgoing messages. + "A string containing header lines, to be inserted in outgoing messages. It is inserted before you edit the message, so you can edit or delete these lines." :type '(choice (const nil) string) @@ -318,7 +406,7 @@ ;;;###autoload (defcustom mail-bury-selects-summary t - "*If non-nil, try to show RMAIL summary buffer after returning from mail. + "If non-nil, try to show RMAIL summary buffer after returning from mail. The functions \\[mail-send-on-exit] or \\[mail-dont-send] select the RMAIL summary buffer before returning, if it exists and this variable is non-nil." @@ -327,7 +415,7 @@ ;;;###autoload (defcustom mail-send-nonascii 'mime - "*Specify whether to allow sending non-ASCII characters in mail. + "Specify whether to allow sending non-ASCII characters in mail. If t, that means do allow it. nil means don't allow it. `query' means ask the user each time. `mime' means add an appropriate MIME header if none already present. @@ -338,7 +426,7 @@ :group 'sendmail) (defcustom mail-use-dsn nil - "*Ask MTA for notification of failed, delayed or successful delivery. + "Ask MTA for notification of failed, delayed or successful delivery. Note that only some MTAs (currently only recent versions of Sendmail) support Delivery Status Notification." :group 'sendmail @@ -352,15 +440,11 @@ (defvar mail-mailer-swallows-blank-line (if (and (string-match "sparc-sun-sunos\\(\\'\\|[^5]\\)" system-configuration) (file-readable-p "/etc/sendmail.cf") - (let ((buffer (get-buffer-create " *temp*"))) - (unwind-protect - (save-excursion - (set-buffer buffer) - (insert-file-contents "/etc/sendmail.cf") - (goto-char (point-min)) - (let ((case-fold-search nil)) - (re-search-forward "^OR\\>" nil t))) - (kill-buffer buffer)))) + (with-temp-buffer + (insert-file-contents "/etc/sendmail.cf") + (goto-char (point-min)) + (let ((case-fold-search nil)) + (re-search-forward "^OR\\>" nil t)))) ;; According to RFC822, "The field-name must be composed of printable ;; ASCII characters (i.e. characters that have decimal values between ;; 33 and 126, except colon)", i.e. any chars except ctl chars, @@ -632,7 +716,7 @@ (while (search-forward "," end t) (or (looking-at "[ \t]") (insert " ")))) - (fill-region-as-paragraph beg end) + (fill-region-as-paragraph beg end arg) ;; Mark all lines except the first as continuations. (goto-char beg) (forward-line 1) @@ -642,92 +726,6 @@ (move-marker end nil) t))) -;;; Set up keymap. - -(if mail-mode-map - nil - (setq mail-mode-map (make-sparse-keymap)) - (define-key mail-mode-map "\M-\t" 'mail-complete) - (define-key mail-mode-map "\C-c?" 'describe-mode) - (define-key mail-mode-map "\C-c\C-f\C-t" 'mail-to) - (define-key mail-mode-map "\C-c\C-f\C-b" 'mail-bcc) - (define-key mail-mode-map "\C-c\C-f\C-f" 'mail-fcc) - (define-key mail-mode-map "\C-c\C-f\C-c" 'mail-cc) - (define-key mail-mode-map "\C-c\C-f\C-s" 'mail-subject) - (define-key mail-mode-map "\C-c\C-f\C-r" 'mail-reply-to) - (define-key mail-mode-map "\C-c\C-f\C-a" 'mail-mail-reply-to) ; author - (define-key mail-mode-map "\C-c\C-f\C-l" 'mail-mail-followup-to) ; list - (define-key mail-mode-map "\C-c\C-t" 'mail-text) - (define-key mail-mode-map "\C-c\C-y" 'mail-yank-original) - (define-key mail-mode-map "\C-c\C-r" 'mail-yank-region) - (define-key mail-mode-map [remap split-line] 'mail-split-line) - (define-key mail-mode-map "\C-c\C-q" 'mail-fill-yanked-message) - (define-key mail-mode-map "\C-c\C-w" 'mail-signature) - (define-key mail-mode-map "\C-c\C-v" 'mail-sent-via) - (define-key mail-mode-map "\C-c\C-c" 'mail-send-and-exit) - (define-key mail-mode-map "\C-c\C-s" 'mail-send) - (define-key mail-mode-map "\C-c\C-i" 'mail-attach-file)) - -(define-key mail-mode-map [menu-bar mail] - (cons "Mail" (make-sparse-keymap "Mail"))) - -(define-key mail-mode-map [menu-bar mail fill] - '("Fill Citation" . mail-fill-yanked-message)) - -(define-key mail-mode-map [menu-bar mail yank] - '("Cite Original" . mail-yank-original)) - -(define-key mail-mode-map [menu-bar mail signature] - '("Insert Signature" . mail-signature)) - -(define-key mail-mode-map [menu-bar mail mail-sep] - '("--")) - -(define-key mail-mode-map [menu-bar mail cancel] - '("Cancel" . mail-dont-send)) - -(define-key mail-mode-map [menu-bar mail send-stay] - '("Send, Keep Editing" . mail-send)) - -(define-key mail-mode-map [menu-bar mail send] - '("Send Message" . mail-send-and-exit)) - -(define-key mail-mode-map [menu-bar headers] - (cons "Headers" (make-sparse-keymap "Move to Header"))) - -(define-key mail-mode-map [menu-bar headers text] - '("Text" . mail-text)) - -(define-key mail-mode-map [menu-bar headers expand-aliases] - '("Expand Aliases" . expand-mail-aliases)) - -(define-key mail-mode-map [menu-bar headers sent-via] - '("Sent Via" . mail-sent-via)) - -(define-key mail-mode-map [menu-bar headers mail-reply-to] - '("Mail Reply To" . mail-mail-reply-to)) - -(define-key mail-mode-map [menu-bar headers mail-followup-to] - '("Mail Followup To" . mail-mail-followup-to)) - -(define-key mail-mode-map [menu-bar headers reply-to] - '("Reply-To" . mail-reply-to)) - -(define-key mail-mode-map [menu-bar headers bcc] - '("Bcc" . mail-bcc)) - -(define-key mail-mode-map [menu-bar headers fcc] - '("Fcc" . mail-fcc)) - -(define-key mail-mode-map [menu-bar headers cc] - '("Cc" . mail-cc)) - -(define-key mail-mode-map [menu-bar headers subject] - '("Subject" . mail-subject)) - -(define-key mail-mode-map [menu-bar headers to] - '("To" . mail-to)) - ;; User-level commands for sending. (defun mail-send-and-exit (&optional arg) @@ -759,8 +757,8 @@ (let (rmail-flag summary-buffer) (and (not arg) (not (one-window-p)) - (save-excursion - (set-buffer (window-buffer (next-window (selected-window) 'not))) + (with-current-buffer + (window-buffer (next-window (selected-window) 'not)) (setq rmail-flag (eq major-mode 'rmail-mode)) (setq summary-buffer (and mail-bury-selects-summary @@ -987,8 +985,7 @@ (and mail-specify-envelope-from (or (mail-envelope-from) user-mail-address)))) (unwind-protect - (save-excursion - (set-buffer tembuf) + (with-current-buffer tembuf (erase-buffer) (unless multibyte (set-buffer-multibyte nil)) @@ -1086,8 +1083,7 @@ (setq fcc-was-found t) (mail-do-fcc delimline))) (if mail-interactive - (save-excursion - (set-buffer errbuf) + (with-current-buffer errbuf (erase-buffer)))) (goto-char (point-min)) (if (let ((case-fold-search t)) @@ -1133,8 +1129,7 @@ (or fcc-was-found (error "No recipients"))) (if mail-interactive - (save-excursion - (set-buffer errbuf) + (with-current-buffer errbuf (goto-char (point-min)) (while (re-search-forward "\n\n* *" nil t) (replace-match "; ")) @@ -1146,22 +1141,22 @@ (kill-buffer errbuf))))) (defun mail-do-fcc (header-end) + (unless (markerp header-end) + (error "Value of `header-end' must be a marker")) (let (fcc-list (rmailbuf (current-buffer)) (time (current-time)) (tembuf (generate-new-buffer " rmail output")) (case-fold-search t)) - (unless (markerp header-end) - (error "Value of `header-end' must be a marker")) (save-excursion (goto-char (point-min)) (while (re-search-forward "^FCC:[ \t]*" header-end t) - (setq fcc-list (cons (buffer-substring (point) - (progn - (end-of-line) - (skip-chars-backward " \t") - (point))) - fcc-list)) + (push (buffer-substring (point) + (progn + (end-of-line) + (skip-chars-backward " \t") + (point))) + fcc-list) (delete-region (match-beginning 0) (progn (forward-line 1) (point)))) (set-buffer tembuf) @@ -1187,8 +1182,8 @@ (while (search-forward "\nFrom " nil t) (forward-char -5) (insert ?>))) - (while fcc-list - (let* ((buffer (find-buffer-visiting (car fcc-list))) + (dolist (fcc fcc-list) + (let* ((buffer (find-buffer-visiting fcc)) (curbuf (current-buffer)) dont-write-the-file buffer-matches-file @@ -1197,8 +1192,7 @@ (forward-line 2) (point)))) (if buffer ;; File is present in a buffer => append to that buffer. - (save-excursion - (set-buffer buffer) + (with-current-buffer buffer (setq buffer-matches-file (and (not (buffer-modified-p)) (verify-visited-file-modtime buffer))) @@ -1239,40 +1233,38 @@ (or buffer-matches-file (progn (if (y-or-n-p (format "Save file %s? " - (car fcc-list))) + fcc)) (save-buffer)) (setq dont-write-the-file t)))) (if max (narrow-to-region (point-min) max)))))) ;; Append to the file directly, ;; unless we've already taken care of it. (unless dont-write-the-file - (if (and (file-exists-p (car fcc-list)) + (if (and (file-exists-p fcc) ;; Check that the file isn't empty. We don't ;; want to insert a newline at the start of an ;; empty file. - (not (zerop (nth 7 (file-attributes (car fcc-list))))) - (mail-file-babyl-p (car fcc-list))) + (not (zerop (nth 7 (file-attributes fcc)))) + (mail-file-babyl-p fcc)) ;; If the file is a Babyl file, ;; convert the message to Babyl format. (let ((coding-system-for-write (or rmail-file-coding-system 'emacs-mule))) - (save-excursion - (set-buffer (get-buffer-create " mail-temp")) + (with-current-buffer (get-buffer-create " mail-temp") (setq buffer-read-only nil) (erase-buffer) (insert "\C-l\n0, unseen,,\n*** EOOH ***\nDate: " (mail-rfc822-date) "\n") (insert-buffer-substring curbuf beg2 end) (insert "\n\C-_") - (write-region (point-min) (point-max) (car fcc-list) t) + (write-region (point-min) (point-max) fcc t) (erase-buffer))) (write-region - (1+ (point-min)) (point-max) (car fcc-list) t))) + (1+ (point-min)) (point-max) fcc t))) (and buffer (not dont-write-the-file) (with-current-buffer buffer - (set-visited-file-modtime)))) - (setq fcc-list (cdr fcc-list)))) + (set-visited-file-modtime)))))) (kill-buffer tembuf))) (defun mail-sent-via () @@ -1281,8 +1273,7 @@ (save-excursion ;; put a marker at the end of the header (let ((end (copy-marker (mail-header-end))) - (case-fold-search t) - to-line) + (case-fold-search t)) (goto-char (point-min)) ;; search for the To: lines and make Sent-via: lines from them ;; search for the next To: line @@ -1625,10 +1616,10 @@ when the message is sent, we apply FUNCTION to ARGS. This is how Rmail arranges to mark messages `answered'." (interactive "P") -;;; This is commented out because I found it was confusing in practice. -;;; It is easy enough to rename *mail* by hand with rename-buffer -;;; if you want to have multiple mail buffers. -;;; And then you can control which messages to save. --rms. +;;; This is commented out because I found it was confusing in practice. +;;; It is easy enough to rename *mail* by hand with rename-buffer +;;; if you want to have multiple mail buffers. +;;; And then you can control which messages to save. --rms. ;;; (let ((index 1) ;;; buffer) ;;; ;; If requested, look for a mail buffer that is modified and go to it. @@ -1687,7 +1678,7 @@ (mail-mode) ;; Disconnect the buffer from its visited file ;; (in case the user has actually visited a file *mail*). -; (set-visited-file-name nil) +;;; (set-visited-file-name nil) (let (initialized) (and (not (and noerase (not (eq noerase 'new)))) @@ -1855,9 +1846,9 @@ (pop-to-buffer "*mail*")) (mail noerase to subject in-reply-to cc replybuffer sendactions)) -;;; Do not add anything but external entries on this page. +;; Do not add anything but external entries on this page. (provide 'sendmail) -;;; arch-tag: 48bc1025-d993-4d31-8d81-2a29491f0626 +;; arch-tag: 48bc1025-d993-4d31-8d81-2a29491f0626 ;;; sendmail.el ends here diff -r 8e25aa911e3e -r 37d0562504bf lisp/mail/smtpmail.el --- a/lisp/mail/smtpmail.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mail/smtpmail.el Sat Dec 10 21:18:28 2005 +0000 @@ -569,7 +569,7 @@ (concat "\0" (smtpmail-cred-user cred) "\0" - (smtpmail-cred-passwd cred)))) + passwd))) (if (or (null (car (setq ret (smtpmail-read-response process)))) (not (integerp (car ret))) (not (equal (car ret) 235))) diff -r 8e25aa911e3e -r 37d0562504bf lisp/man.el --- a/lisp/man.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/man.el Sat Dec 10 21:18:28 2005 +0000 @@ -262,7 +262,7 @@ (defvar Man-name-regexp "[-a-zA-Z0-9_­+][-a-zA-Z0-9_.:­+]*" "Regular expression describing the name of a manpage (without section).") -(defvar Man-section-regexp "[0-9][a-zA-Z+]*\\|[LNln]" +(defvar Man-section-regexp "[0-9][a-zA-Z0-9+]*\\|[LNln]" "Regular expression describing a manpage section within parentheses.") (defvar Man-page-header-regexp diff -r 8e25aa911e3e -r 37d0562504bf lisp/mh-e/ChangeLog --- a/lisp/mh-e/ChangeLog Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mh-e/ChangeLog Sat Dec 10 21:18:28 2005 +0000 @@ -1,3 +1,190 @@ +2005-12-04 Bill Wohler + + * mh-customize.el (mh-sortm-args): Sync docstrings with manual. + (mh-invisible-header-fields-internal): Add X-Bugzilla-* and + X-Virus-Scanned. + + * mh-customize.el (mh-insert-signature-hook): Rename + mh-letter-insert-signature-hook to mh-insert-signature-hook. + + * mh-comp.el (mh-insert-signature): Ditto. + + * mh-customize.el (mh-fetch-x-image-url): Change default from 'ask + to nil. Remove t option. Sync docstring with manual (closes SF + #831278). + (mh-invisible-header-fields-internal): Remove X-Image-URL so that + users can see it, look it up in the manual's index, and discover + mh-fetch-x-image-url (closes SF #831278). + + * mh-customize.el (mh-new-messages-folders): Rename from + mh-index-new-messages-folders. + (mh-ticked-messages-folders): Rename from + mh-index-ticked-messages-folders. + + * mh-index.el (mh-index-sequenced-messages) + (mh-index-new-messages): Ditto. + + * mh-comp.el (mh-forward): Went over all uses of the word "RANGE" + in the docstrings and made usage consistent. Generally speaking, + "messages in range" and "range of messages" is redundant and just + "range" can be used in most circumstances. Also ensured that + mh-interactive-range was mentioned in all interactive functions + that use a range which describes the range argument for both users + and programmers. + + * mh-e.el (mh-delete-msg-no-motion, mh-refile-msg) + (mh-refile-or-write-again, mh-rescan-folder, mh-undo) + (mh-visit-folder, mh-scan-folder, mh-regenerate-headers) + (mh-notate-user-sequences, mh-delete-msg-from-seq, mh-catchup): + Ditto. + + * mh-funcs.el (mh-copy-msg, mh-pack-folder, mh-pack-folder-1): + Ditto. + + * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist): Ditto. + + * mh-print.el (mh-ps-print-range, mh-ps-print-msg) + (mh-ps-print-msg-file, mh-print-msg): Ditto. + + * mh-seq.el (mh-put-msg-in-seq, mh-range-to-msg-list) + (mh-narrow-to-range, mh-toggle-tick): Ditto. + + +2005-12-01 Bill Wohler + + Rewrote Reading Mail chapter in manual which affected mh-show + customization group and related functions. + + * mh-comp.el (mh-letter-mode): Use mh-highlight-citation-style + instead of mh-highlight-citation-p. + (mh-letter-toggle-header-field-display): "Ellipsed" isn't a word, + I think, so use "truncated". + + * mh-customize.el (mh-folder, mh-folder-faces): Group's manual + section is Folders, not Organizing. Parent of mh-folder-faces is + mh-folder, not mh-show. + (mh-speed): Rename to mh-speedbar for consistency with mh-toolbar. + (mh-thread): New group that corresponds with manual's Threading + chapter. + (mh-letter-faces): Group's manual section is Editing Drafts, not + Sending Mail. + (mh-sortm-args): New customization variable that used to be a + defvar. + (mh-index-new-messages-folders, mh-index-ticked-messages-folders): + Move from mh-index group to mh-folders group. + (mh-alias-local-users-prefix, mh-large-folder) + (mh-recursive-folders-flag, mh-before-quit-hook) + (mh-folder-mode-hook, mh-kill-folder-suppress-prompt-hook) + (mh-quit-hook, mh-refile-msg-hook): Move from mh-show group to + mh-folder group. + (mh-highlight-citation-style): Rename from + mh-highlight-citation-p. Sync docstrings with manual. + (mh-mhl-format-file): Rename from mhl-formfile. Sync docstrings + with manual. + (mh-show-threads-flag): Move from mh-show group to mh-thread + group. + (mh-find-path-hook): Move from mh-show group to mh-e group. + (mh-folder-updated-hook): Add to mh-folder group. + (mh-forward-hook): Move from mh-folder to mh-sending-mail group. + (mh-unseen-updated-hook): Move from mh-show to mh-sequences group. + (mh-bury-show-buffer-flag, mh-clean-message-header-flag) + (mh-decode-mime-flag, mh-display-buttons-for-alternatives-flag) + (mh-display-buttons-for-inline-parts-flag) + (mh-do-not-confirm-flag, mh-fetch-x-image-url) + (mh-graphical-smileys-flag, mh-graphical-emphasis-flag) + (mh-invisible-header-fields-default, mh-invisible-header-fields) + (mh-lpr-command-format, mh-max-inline-image-height) + (mh-max-inline-image-width) + (mh-mime-save-parts-default-directory, mh-print-background-flag) + (mh-show-maximum-size, mh-show-use-goto-addr-flag) + (mh-show-use-xface-flag, mh-store-default-directory) + (mh-summary-height, mh-delete-msg-hook + (mh-show-hook, mh-show-mode-hook): Sync docstrings with manual. + + * mh-e.el + (mh-scan-format-mh, mh-scan-good-msg-regexp) + (mh-scan-deleted-msg-regexp, mh-scan-refiled-msg-regexp) + (mh-scan-cur-msg-number-regexp, mh-scan-subject-regexp): Use + non-fontification instead of non-fontifying. + (mh-header-display): Use mh-mhl-format-file instead of + mhl-formfile. Sync docstrings with manual. + (mh-next-undeleted-msg, mh-previous-undeleted-msg): Rename arg to + count. Sync docstrings with manual. + (mh-refile-or-write-again): Use output from mh-write-msg-to-file + so that message doesn't change when using this command. Sync + docstrings with manual. + (mh-page-msg, mh-previous-page): Rename arg to lines. Sync + docstrings with manual. + (mh-write-msg-to-file): Rename msg to message. Rename no-headers + to no-header. Sync docstrings with manual. + (mh-ps-print-map): Delete keybindings for deleted commands + mh-ps-print-toggle-mime and mh-ps-print-msg-show. + (mh-help-messages): Updated printing help. + (mh-delete-msg, mh-delete-msg-no-motion, mh-first-msg) + (mh-last-msg, mh-previous-unread-msg, mh-next-button) + (mh-prev-button, mh-folder-toggle-mime-part) + (mh-folder-inline-mime-part, mh-folder-save-mime-part) + (mh-next-unread-msg, mh-toggle-mime-buttons): Sync docstrings with + manual. + + * mh-funcs.el (mh-sortm-args): Now a customization option and + in mh-customize.el. + (mh-pipe-msg): Rename include-headers to include-header. Sync + docstrings with manual. + (mh-burst-digest, mh-page-digest, mh-page-digest-backwards) + (mh-store-msg): Sync docstrings with manual. + + * mh-mime.el (mh-mime-save-parts): Rename arg to prompt. Sync + docstrings with manual. + (mh-toggle-mh-decode-mime-flag): Use English in message, not Lisp. + Sync docstrings with manual. + (mh-mm-display-part, mh-mm-inline-message): Use + mh-highlight-citation-style instead of mh-highlight-citation-p. + (mh-press-button): Sync docstrings with manual. + (mh-display-with-external-viewer): Fix default output in + minibuffer. Sync docstrings with manual. + + * mh-print.el: (mh-ps-print-mime, mh-ps-print-toggle-mime): + Deleted. + (mh-ps-print-color-option): Incorporate docstring from + ps-print-color-p. + (mh-ps-spool-buffer): Remove unused code. Fix indent. Slimline + docstring. + (mh-ps-spool-msg): Slimline docstring. Rename from + mh-ps-spool-a-msg. Rewrote to use existing show buffer when + available. + (mh-ps-print-range): Extract method from common code in + mh-ps-print-msg and mh-ps-print-msg-file. + (mh-ps-print-preprint): Clean docstring. Use filename "mh-%s". + (mh-ps-print-msg-show): Delete. Can use either + mh-ps-print-msg-show or mh-ps-print-msg-show to same effect with + new code in mh-ps-spool-msg. + (mh-print-msg): Use mh-mhl-format-file instead of mhl-formfile. + Sync docstrings with manual. + (mh-ps-print-msg, mh-ps-print-msg-file) + (mh-ps-print-toggle-faces, mh-ps-print-toggle-color): Sync + docstrings with manual. + + * mh-utils.el (mh-show-ps-print-msg-show, + mh-show-ps-print-toggle-mime): Delete. + (mh-show-ps-print-map): Updated accordingly. + (mh-show-mode): Use mh-highlight-citation-style instead of + mh-highlight-citation-p. + (mh-show-xface, mh-display-msg): Use mh-mhl-format-file instead of + mhl-formfile. + (mh-show): Use mh-mhl-format-file instead of mhl-formfile. Sync + docstrings with manual. + (mh-show-font-lock-fontify-region, mh-modify, mh-goto-msg): Sync + docstrings with manual. + +2005-12-01 Bill Wohler + + * mh-init.el (mh-defface-compat): Checkdoc fix. + + * mh-junk.el (mh-bogofilter-blacklist, mh-bogofilter-whitelist): + Bogofilter is lowercase except at beginning of sentence and in + titles. + 2005-11-04 Bill Wohler * mh-customize.el (mh-min-colors-defined-flag, mh-defface-compat): diff -r 8e25aa911e3e -r 37d0562504bf lisp/mh-e/mh-comp.el --- a/lisp/mh-e/mh-comp.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mh-e/mh-comp.el Sat Dec 10 21:18:28 2005 +0000 @@ -327,18 +327,15 @@ ;;;###mh-autoload (defun mh-forward (to cc &optional range) - "Forward message(s). + "Forward message. You are prompted for the TO and CC recipients. You are given a draft to edit that looks like it would if you had run the MH command \"forw\". You are given a chance to add some text. -You can forward several messages by using a RANGE. All of the messages in the -range are inserted into your draft. Check the documentation of +You can forward several messages by using a RANGE. Check the documentation of `mh-interactive-range' to see how RANGE is read in interactive use. -The default message is the current message. - See also `mh-compose-forward-as-mime-flag', `mh-forward-subject-format', and `mh-send'." (interactive (list (mh-interactive-read-address "To: ") @@ -1000,8 +997,8 @@ (mh-funcall-if-exists mh-toolbar-init :letter) (make-local-variable 'font-lock-defaults) (cond - ((or (equal mh-highlight-citation-p 'font-lock) - (equal mh-highlight-citation-p 'gnus)) + ((or (equal mh-highlight-citation-style 'font-lock) + (equal mh-highlight-citation-style 'gnus)) ;; Let's use font-lock even if gnus is used in show-mode. The reason ;; is that gnus uses static text properties which are not appropriate ;; for a buffer that will be edited. So the choice here is either fontify @@ -1146,7 +1143,7 @@ A signature separator (\"-- \") will be added if the signature block does not contain one and `mh-signature-separator-flag' is on. -The value of `mh-letter-insert-signature-hook' is a list of functions to be +The value of `mh-insert-signature-hook' is a list of functions to be called, with no arguments, after the signature is inserted. These functions may access the actual name of the file or the function used to insert the signature with `mh-signature-file-name'. @@ -1184,7 +1181,7 @@ (funcall mh-signature-file-name))))) (save-restriction (widen) - (run-hooks 'mh-letter-insert-signature-hook)) + (run-hooks 'mh-insert-signature-hook)) (goto-char (point-min)) (when (and (not (mh-file-is-vcard-p mh-signature-file-name)) mh-signature-separator-flag @@ -1950,7 +1947,7 @@ (defun mh-letter-toggle-header-field-display (arg) "Toggle display of header field at point. -Use this command to display ellipsed header fields. This command is a toggle +Use this command to display truncated header fields. This command is a toggle so entering it again will hide the field. This command takes a prefix argument ARG: if negative then the field is hidden, if positive then the field is displayed." diff -r 8e25aa911e3e -r 37d0562504bf lisp/mh-e/mh-customize.el --- a/lisp/mh-e/mh-customize.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mh-e/mh-customize.el Sat Dec 10 21:18:28 2005 +0000 @@ -117,7 +117,7 @@ (defgroup mh-folder nil "Organizing your mail with folders." :prefix "mh-" - :link '(custom-manual "(mh-e)Organizing") + :link '(custom-manual "(mh-e)Folders") :group 'mh-e) (defgroup mh-folder-selection nil @@ -186,12 +186,18 @@ :link '(custom-manual "(mh-e)Reading Mail") :group 'mh-e) -(defgroup mh-speed nil +(defgroup mh-speedbar nil "The speedbar." :prefix "mh-speed-" :link '(custom-manual "(mh-e)Speedbar") :group 'mh-e) +(defgroup mh-thread nil + "Threading." + :prefix "mh-thread-" + :link '(custom-manual "(mh-e)Threading") + :group 'mh-e) + (defgroup mh-toolbar nil "The toolbar" :link '(custom-manual "(mh-e)Toolbar") @@ -215,10 +221,10 @@ (defgroup mh-folder-faces nil "Faces used in scan listing." - :link '(custom-manual "(mh-e)Organizing") + :link '(custom-manual "(mh-e)Folders") :prefix "mh-" :group 'mh-faces - :group 'mh-show) + :group 'mh-folder) (defgroup mh-index-faces nil "Faces used in searching." @@ -229,7 +235,7 @@ (defgroup mh-letter-faces nil "Faces used in message drafts." - :link '(custom-manual "(mh-e)Sending Mail") + :link '(custom-manual "(mh-e)Editing Drafts") :prefix "mh-" :group 'mh-faces :group 'mh-letter) @@ -250,7 +256,7 @@ -;;; Emacs interface to the MH mail system (:group mh) +;;; Emacs interface to the MH mail system (:group mh-e) (eval-when (compile) (setq mh-variant 'none)) @@ -346,7 +352,7 @@ :group 'mh-alias) (defcustom mh-alias-local-users-prefix "local." - "*String prepended to the real names of users from the password file. + "*String prefixed to the real names of users from the password file. This option can also be set to `Use Login'. For example, consider the following password file entry: @@ -378,6 +384,41 @@ ;;; Organizing Your Mail with Folders (:group 'mh-folder) +(defcustom mh-new-messages-folders t + "Folders searched for the \"unseen\" sequence. + +Set this option to \"Inbox\" to search the \"+inbox\" folder or \"All\" to +search all of the top level folders. Otherwise, list the folders that should +be searched with the \"Choose Folders\" menu item. + +See also `mh-recursive-folders-flag'." + :type '(choice (const :tag "Inbox" t) + (const :tag "All" nil) + (repeat :tag "Choose Folders" (string :tag "Folder"))) + :group 'mh-folder) + +(defcustom mh-ticked-messages-folders t + "Folders searched for `mh-tick-seq'. + +Set this option to \"Inbox\" to search the \"+inbox\" folder or \"All\" to +search all of the top level folders. Otherwise, list the folders that should +be searched with the \"Choose Folders\" menu item. + +See also `mh-recursive-folders-flag'." + :type '(choice (const :tag "Inbox" t) + (const :tag "All" nil) + (repeat :tag "Choose Folders" (string :tag "Folder"))) + :group 'mh-folder) + +(defcustom mh-large-folder 200 + "The number of messages that indicates a large folder. +If a folder is deemed to be large, that is the number of messages in it exceed +this value, then confirmation is needed when it is visited. Even when +`mh-show-threads-flag' is non-nil, the folder is not automatically threaded, if +it is large. If set to nil all folders are treated as if they are small." + :type '(choice (const :tag "No Limit") integer) + :group 'mh-folder) + (defcustom mh-recenter-summary-flag nil "*Non-nil means to recenter the summary window. If this option is turned on, recenter the summary window when the show window @@ -385,6 +426,21 @@ :type 'boolean :group 'mh-folder) +(defcustom mh-recursive-folders-flag nil + "*Non-nil means that commands which operate on folders do so recursively." + :type 'boolean + :group 'mh-folder) + +(defcustom mh-sortm-args nil + "*Additional arguments for \"sortm\"\\. + +This option is consulted when a prefix argument is used with +\\[mh-sort-folder]. Normally default arguments to \"sortm\" are specified in +the MH profile. This option may be used to provide an alternate view. For +example, \"'(\"-nolimit\" \"-textfield\" \"subject\")\" is a useful setting." + :type 'string + :group 'mh-folder) + ;;; Folder Selection (:group 'mh-folder-selection) @@ -657,18 +713,6 @@ ;;; Searching (:group 'mh-index) -(defcustom mh-index-new-messages-folders t - "Folders searched for the \"unseen\" sequence. -Set this option to \"Inbox\" to search the \"+inbox\" folder or \"All\" to -search all of the top level folders. Otherwise, list the folders that should -be searched with the \"Choose Folders\" menu item. - -See also `mh-recursive-folders-flag'." - :group 'mh-index - :type '(choice (const :tag "Inbox" t) - (const :tag "All" nil) - (repeat :tag "Choose Folders" (string :tag "Folder")))) - (defcustom mh-index-program nil "Indexing program that MH-E shall use. The default setting of this option is `Auto-detect' which means that MH-E will @@ -687,18 +731,6 @@ (const :tag "grep" grep)) :group 'mh-index) -(defcustom mh-index-ticked-messages-folders t - "Folders searched for `mh-tick-seq'. -Set this option to \"Inbox\" to search the \"+inbox\" folder or \"All\" to -search all of the top level folders. Otherwise, list the folders that should -be searched with the \"Choose Folders\" menu item. - -See also `mh-recursive-folders-flag'." - :group 'mh-index - :type '(choice (const :tag "Inbox" t) - (const :tag "All" nil) - (repeat :tag "Choose Folders" (string :tag "Folder")))) - ;;; Dealing with Junk Mail (:group 'mh-junk) @@ -747,9 +779,9 @@ "Spam program that MH-E should use. The default setting of this option is \"Auto-detect\" which means that MH-E -will automatically choose one of SpamAssassin, Bogofilter, or SpamProbe in -that order. If, for example, you have both SpamAssassin and Bogofilter -installed and you want to use BogoFilter, then you can set this option to +will automatically choose one of SpamAssassin, bogofilter, or SpamProbe in +that order. If, for example, you have both SpamAssassin and bogofilter +installed and you want to use bogofilter, then you can set this option to \"Bogofilter\"." :type '(choice (const :tag "Auto-detect" nil) (const :tag "SpamAssassin" spamassassin) @@ -1167,98 +1199,153 @@ ;;; Reading Your Mail (:group 'mh-show) (defcustom mh-bury-show-buffer-flag t - "*Non-nil means that the displayed show buffer for a folder is buried." + "*Non-nil means show buffer is buried. + +One advantage of not burying the show buffer is that one can delete the show +buffer more easily in an electric buffer list because of its proximity to its +associated MH-Folder buffer. Try running \\[electric-buffer-list] to see what +I mean." :type 'boolean :group 'mh-show) (defcustom mh-clean-message-header-flag t "*Non-nil means remove extraneous header fields. -The header fields listed in the `mh-invisible-header-fields-default' option -are hidden, although you can check off any field that you would like to see. -Header fields that you would like to hide that aren't listed can be added to -the `mh-invisible-header-fields' option." + +See also `mh-invisible-header-fields-default' and +`mh-invisible-header-fields'." :type 'boolean :group 'mh-show) (defcustom mh-decode-mime-flag (not (not (locate-library "mm-decode"))) - "*Non-nil means that Gnus is used to show MIME attachments with Gnus." + "*Non-nil means attachments are handled\\. + +MH-E can handle attachments as well if the Gnus `mm-decode' library is +present. If so, this option will be on. Otherwise, you'll see the MIME body +parts rather than text or attachments. There isn't much point in turning off +this option; however, you can inspect it if it appears that the body parts are +not being interpreted correctly or toggle it with the command +\\[mh-toggle-mh-decode-mime-flag] to view the raw message. + +This option also controls the display of quoted-printable messages and other +graphical widgets. See the options `mh-graphical-smileys-flag' and +`mh-graphical-emphasis-flag'." :type 'boolean :group 'mh-show) (defcustom mh-display-buttons-for-alternatives-flag nil - "*Non-nil means display buttons for all MIME alternatives. -Default behavior is to display only the preferred alternative. If this -variable is non-nil, then the preferred part is shown inline and buttons -are shown for each of the other alternatives." + "*Non-nil means display buttons for all alternative attachments. + +Sometimes, a mail program will produce multiple alternatives of the attachment +in increasing degree of faithfulness to the original content. By default, only +the preferred alternative is displayed. If this option is on, then the +preferred part is shown inline and buttons are shown for each of the other +alternatives." :type 'boolean :group 'mh-show) (defcustom mh-display-buttons-for-inline-parts-flag nil - "*Non-nil means display buttons for all inline MIME parts. -If non-nil, buttons are displayed for all MIME parts. Inline parts start off -in displayed state but they can be hidden by clicking the button. If nil no -buttons are shown for inline parts." + "*Non-nil means display buttons for all inline attachments\\. + +The sender can request that attachments should be viewed inline so that they +do not really appear like an attachment at all to the reader. Most of the +time, this is desirable, so by default MH-E suppresses the buttons for inline +attachments. On the other hand, you may receive code or HTML which the sender +has added to his message as inline attachments so that you can read them in +MH-E. In this case, it is useful to see the buttons so that you know you don't +have to cut and paste the code into a file; you can simply save the +attachment. + +If you want to make the buttons visible for inline attachments, you can use +the command \\[mh-toggle-mime-buttons] to toggle the visibility of these +buttons. You can turn on these buttons permanently by turning on this option. + +MH-E cannot display all attachments inline however. It can display +text (including HTML) and images." :type 'boolean :group 'mh-show) (defcustom mh-do-not-confirm-flag nil - "*Non-nil means do not prompt for confirmation. + "*Non-nil means non-reversible commands do not prompt for confirmation. + Commands such as `mh-pack-folder' prompt to confirm whether to process -outstanding moves and deletes or not before continuing. A non-nil setting will -perform the action--which is usually desired but cannot be retracted--without -question." +outstanding moves and deletes or not before continuing. Turning on this option +means that these actions will be performed--which is usually desired but +cannot be retracted--without question." :type 'boolean :group 'mh-show) -(defcustom mh-fetch-x-image-url 'ask - "*Control fetching of `X-Image-URL:' header field image. -If set to \"Always fetch\" (t), the image is always fetched. You probably want -to avoid this setting for privacy and DOS (denial of service) reasons. For -example, fetching a URL can tip off a spammer that you've read his email. -Someone may also flood your network and fill your disk drive by sending a -torrent of messages, each specifying a unique URL to a very large file. - -If set to \"Ask before fetching\" ('ask), you are prompted before the image is -fetched. MH-E will remember your reply and will either use the already fetched -image the next time the same URL is encountered or silently skip it if you -didn't fetch it the first time. This is the default. - -If set to \"Never fetch\" (nil), images are never fetched and only displayed -if they are already present in the cache. - -The cache of images is found in the directory `.mhe-x-image-cache' within your -MH directory. To see how you can add your own face to the `From:' field, see -`mh-x-face-file'. - -This setting only has effect if `mh-show-use-xface-flag' is non-nil." - - :type '(choice (const :tag "Always fetch" t) - (const :tag "Ask before fetching" ask) - (const :tag "Never fetch" nil)) +(defcustom mh-fetch-x-image-url nil + "*Control fetching of \"X-Image-URL:\" header field image. + +Ths option controls the fetching of the \"X-Image-URL:\" header field image +with the following values: + +Ask Before Fetching + You are prompted before the image is fetched. MH-E will remember + your reply and will either use the already fetched image the next + time the same URL is encountered or silently skip it if you didn't + fetch it the first time. This is a good setting. + +Never Fetch + Images are never fetched and only displayed if they are already + present in the cache. This is the default. + +There isn't a value of \"Always Fetch\" for privacy and DOS (denial of +service) reasons. For example, fetching a URL can tip off a spammer that +you've read his email (which is why you shouldn't blindly answer yes if you've +set this option to \"Ask Before Fetching\"). Someone may also flood your +network and fill your disk drive by sending a torrent of messages, each +specifying a unique URL to a very large file. + +The cache of images is found in the directory \".mhe-x-image-cache\" within +your MH directory. You can add your own face to the \"From:\" field too. See +Info node `(mh-e)Picture'. + +This setting only has effect if the option `mh-show-use-xface-flag' is turned +on." + + :type '(choice (const :tag "Ask Before Fetching" ask) + (const :tag "Never Fetch" nil)) :group 'mh-show) (defcustom mh-graphical-smileys-flag t "*Non-nil means graphical smileys are displayed. -Non-nil means that small graphics will be used in the show buffer instead of -patterns like :-), ;-) etc. The setting only has effect if -`mh-decode-mime-flag' is non-nil." + +It is a long standing custom to inject body language using a cornucopia of +punctuation, also known as the \"smileys\". MH-E can render these as graphical +widgets if this option is turned on, which it is by default. Smileys include +patterns such as :-) and ;-). + +This option is disabled if the option `mh-decode-mime-flag' is turned off." :type 'boolean :group 'mh-show) (defcustom mh-graphical-emphasis-flag t "*Non-nil means graphical emphasis is displayed. -Non-nil means that _underline_ will be underlined, *bold* will appear in bold, -/italic/ will appear in italic etc. See `gnus-emphasis-alist' for the whole -list. The setting only has effect if `mh-decode-mime-flag' is non-nil." + +A few typesetting features are indicated in ASCII text with certain +characters. If your terminal supports it, MH-E can render these typesetting +directives naturally if this option is turned on, which it is by default. For +example, _underline_ will be underlined, *bold* will appear in bold, /italics/ +will appear in italics, and so on. See the option `gnus-emphasis-alist' for +the whole list. + +This option is disabled if the option `mh-decode-mime-flag' is turned off." :type 'boolean :group 'mh-show) -(defcustom mh-highlight-citation-p 'gnus - "How to highlight citations in show buffers. -The gnus method uses a different color for each indentation." - :type '(choice (const :tag "Use Gnus" gnus) - (const :tag "Use font-lock" font-lock) - (const :tag "Don't fontify" nil)) +(defcustom mh-highlight-citation-style 'gnus + "Style for highlighting citations. + +If the sender of the message has cited other messages in his message, then +MH-E will highlight these citations to emphasize the sender's actual response. +This option can be customized to change the highlighting style. The +\"Multicolor\" method uses a different color for each indentation while the +\"Monochrome\" method highlights all citations in red. To disable highlighting +of citations entirely, choose \"None\"." + :type '(choice (const :tag "Multicolor" gnus) + (const :tag "Monochrome" font-lock) + (const :tag "None" nil)) :group 'mh-show) ;; Keep fields alphabetized. Mention source, if known. @@ -1332,6 +1419,7 @@ "X-Authentication-Warning:" ; sendmail "X-Beenthere:" ; Mailman mailing list manager "X-Bogosity:" ; bogofilter + "X-Bugzilla-*" ; Bugzilla "X-Complaints-To:" "X-Cron-Env:" "X-DMCA" @@ -1357,7 +1445,6 @@ "X-Habeas-SWE-7:" ; Spam "X-Habeas-SWE-8:" ; Spam "X-Habeas-SWE-9:" ; Spam - "X-Image-URL:" ; URL equivalent of X-Face and Face "X-Info:" ; NTMail "X-Juno-" ; Juno "X-List-Host:" ; Unknown mailing list managers @@ -1421,6 +1508,7 @@ "X-UIDL:" "X-USANET-" ; usa.net "X-UserInfo1:" + "X-Virus-Scanned" ; amavisd-new "X-VSMLoop:" ; NTMail "X-Vms-To:" "X-WebTV-Signature:" @@ -1470,10 +1558,12 @@ (defcustom mh-invisible-header-fields-default nil "*List of hidden header fields. + The header fields listed in this option are hidden, although you can check off -any field that you would like to see. Header fields that you would like to -hide that aren't listed can be added to the `mh-invisible-header-fields' -option. +any field that you would like to see. + +Header fields that you would like to hide that aren't listed can be added to +the option `mh-invisible-header-fields'. See also `mh-clean-message-header-flag'." :type `(set ,@(mapcar (lambda (x) `(const ,x)) @@ -1485,11 +1575,14 @@ (defcustom mh-invisible-header-fields nil "*Additional header fields to hide. + Header fields that you would like to hide that aren't listed in `mh-invisible-header-fields-default' can be added to this option with a couple of caveats. Regular expressions are not allowed. Unique fields should have a `:' suffix; otherwise, the element can be used to render invisible an entire -class of fields that start with the same prefix. +class of fields that start with the same prefix. If you think a header field +should be generally ignored, report a bug (see URL +`https://sourceforge.net/tracker/?group_id=13357&atid=113357'). See also `mh-clean-message-header-flag'." @@ -1500,146 +1593,184 @@ :group 'mh-show) (defcustom mh-lpr-command-format "lpr -J '%s'" - "*Format for Unix command that prints a message. -The string should be a Unix command line, with the string '%s' where -the job's name (folder and message number) should appear. The formatted -message text is piped to this command when you type \\`\\[mh-print-msg]'." + "*Command used to print\\. + +This option contains the Unix command line which performs the actual printing +for the \\[mh-print-msg] command. The string can contain one escape, \"%s\", +which is replaced by the name of the folder and the message number and is +useful for print job names. I use \"mpage -h'%s' -b Letter -H1of -mlrtb -P\" +which produces a nice header and adds a bit of margin so the text fits within +my printer's margins. + +This options is not used by the commands \\[mh-ps-print-msg] or +\\[mh-ps-print-msg-file]." :type 'string :group 'mh-show) (defcustom mh-max-inline-image-height nil - "*Maximum inline image height if Content-Disposition is not present. -If nil, image will be displayed if its height is smaller than the height of -the window." + "*Maximum inline image height if \"Content-Disposition:\" is not present. + +Some older mail programs do not insert this needed plumbing to tell +MH-E whether to display the attachments inline or not. If this is the +case, MH-E will display these images inline if they are smaller than +the window. However, you might want to allow larger images to be +displayed inline. To do this, you can change the options +`mh-max-inline-image-width' and `mh-max-inline-image-height' from their +default value of zero to a large number. The size of your screen is a +good choice for these numbers." :type '(choice (const nil) integer) :group 'mh-show) (defcustom mh-max-inline-image-width nil - "*Maximum inline image width if Content-Disposition is not present. -If nil, image will be displayed if its width is smaller than the width of the -window." + "*Maximum inline image width if \"Content-Disposition:\" is not present. + +Some older mail programs do not insert this needed plumbing to tell +MH-E whether to display the attachments inline or not. If this is the +case, MH-E will display these images inline if they are smaller than +the window. However, you might want to allow larger images to be +displayed inline. To do this, you can change the options +`mh-max-inline-image-width' and `mh-max-inline-image-height' from their +default value of zero to a large number. The size of your screen is a +good choice for these numbers." :type '(choice (const nil) integer) :group 'mh-show) +(defcustom mh-mhl-format-file nil + "*Specifies the format file to pass to the \"mhl\" program. + +Normally MH-E takes care of displaying messages itself (rather than calling an +MH program to do the work). If you'd rather have \"mhl\" display the +message (within MH-E), change this option from its default value of \"Use +Default mhl Format (Printing Only)\". + +You can set this option to \"Use Default mhl Format\" to get the same output +as you would get if you ran \"mhl\" from the shell. + +If you have a format file that you want MH-E to use, you can set this option +to \"Specify an mhl Format File\" and enter the name of your format file. Your +format file should specify a non-zero value for \"overflowoffset\" to allow +MH-E to parse the header. Note that \"mhl\" is always used for printing and +forwarding; in this case, the value of this option is consulted if you have +specified a format file." + :type '(choice (const :tag "Use Default mhl Format (Printing Only)" nil) + (const :tag "Use Default mhl Format" t) + (file :tag "Specify an mhl Format File")) + :group 'mh-show) + (defcustom mh-mime-save-parts-default-directory t - "Default directory to use for `mh-mime-save-parts'. -If nil, prompt and set for next time the command is used during same session. -If t, prompt always" - :type '(choice (const :tag "Prompt the first time" nil) - (const :tag "Prompt always" t) + "Default directory to use for \\\\[mh-mime-save-parts]. + +The default value for this option is \"Prompt Always\" so that you are always +prompted for the directory in which to save the attachments. However, if you +usually use the same directory within a session, then you can set this option +to \"Prompt the First Time\" to avoid the prompt each time. you can make this +directory permanent by choosing \"Directory\" and entering the directory's +name." + :type '(choice (const :tag "Prompt the First Time" nil) + (const :tag "Prompt Always" t) directory) :group 'mh-show) (defcustom mh-print-background-flag nil - "*Non-nil means messages should be printed in the background. -WARNING: do not delete the messages until printing is finished; -otherwise, your output may be truncated." - :type 'boolean - :group 'mh-show) - -(defcustom mh-recursive-folders-flag nil - "*Non-nil means that commands which operate on folders do so recursively." + "*Non-nil means messages should be printed in the background\\. + +Normally messages are printed in the foreground. If this is slow on your +system, you may elect to turn off this option to print in the background. + +WARNING: If you do this, do not delete the message until it is printed or else +the output may be truncated. + +This option is not used by the commands \\[mh-ps-print-msg] or +\\[mh-ps-print-msg-file]." :type 'boolean :group 'mh-show) (defcustom mh-show-maximum-size 0 "*Maximum size of message (in bytes) to display automatically. -Provides an opportunity to skip over large messages which may be slow to load. -Use a value of 0 to display all messages automatically regardless of size." + +This option provides an opportunity to skip over large messages which may be +slow to load. The default value of 0 means that all message are shown +regardless of size." :type 'integer :group 'mh-show) -(defcustom mh-show-threads-flag nil - "Non-nil means new folders start in threaded mode. -Threading large number of messages can be time consuming. So if the flag is -non-nil then threading will be done only if the number of messages being -threaded is less than `mh-large-folder'." - :type 'boolean - :group 'mh-show) - -;; Use goto-addr if it was already loaded (which probably sets this -;; variable to t), or if this variable is otherwise set to t. (defcustom mh-show-use-goto-addr-flag (and (boundp 'goto-address-highlight-p) goto-address-highlight-p) - "*Non-nil means highlight URLs and email addresses. -The `goto-addr' module is used." + "*Non-nil means highlight URLs and email addresses\\. + +To send a message using the highlighted email address or to view the web page +for the highlighted URL, use the middle mouse button or +\\[goto-address-at-point]. + +See Info node `(mh-e)Sending Mail' to see how to configure Emacs to send the +message using MH-E. + +The default value of this option comes from the value of +`goto-address-highlight-p'." :type 'boolean :group 'mh-show) (defcustom mh-show-use-xface-flag (>= emacs-major-version 21) - "*Non-nil means display face images in `mh-show-mode'. - -MH-E can display the content of `Face:', `X-Face:', and `X-Image-URL:' header -fields. If any of these fields occur in the header of your message, the -sender's face will appear in the `From:' header field. If more than one of -these fields appear, then the first field found in the order `Face:', -`X-Face:', and `X-Image-URL:' will be used. Note that versions of GNU Emacs -prior to 21.1 don't support the display of inline images, so face images are -not displayed in these versions. + "*Non-nil means display face images in MH-show buffers. + +MH-E can display the content of \"Face:\", \"X-Face:\", and \"X-Image-URL:\" +header fields. If any of these fields occur in the header of your message, the +sender's face will appear in the \"From:\" header field. If more than one of +these fields appear, then the first field found in the order \"Face:\", +\"X-Face:\", and \"X-Image-URL:\" will be used. The option `mh-show-use-xface-flag' is used to turn this feature on and off. This feature will be turned on by default if your system supports it. -The first header field used, if present, is the Gnus-specific `Face:' field. -The `Face:' field appeared in GNU Emacs 21 and XEmacs. For more information, +The first header field used, if present, is the Gnus-specific \"Face:\" field. +The \"Face:\" field appeared in GNU Emacs 21 and XEmacs. For more information, see URL `http://quimby.gnus.org/circus/face/'. Next is the traditional -`X-Face:' header field. The display of this field requires the `uncompface' -program (see URL `ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z'). -Recent versions of XEmacs have internal support for `X-Face:' images. If your -version of XEmacs does not, then you'll need both `uncompface' and the x-face +\"X-Face:\" header field. The display of this field requires the +\"uncompface\" program (see URL +`ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.z'). Recent versions +of XEmacs have internal support for \"X-Face:\" images. If your version of +XEmacs does not, then you'll need both \"uncompface\" and the x-face package (see URL `ftp://ftp.jpl.org/pub/elisp/'). -Finally, MH-E will display images referenced by the `X-Image-URL:' header -field if neither the `Face:' nor the `X-Face:' fields are present. The display -of the images requires `wget' (see URL -`http://www.gnu.org/software/wget/wget.html'), `fetch', or `curl' to fetch the -image and the `convert' program from the ImageMagick suite (see URL +Finally, MH-E will display images referenced by the \"X-Image-URL:\" header +field if neither the \"Face:\" nor the \"X-Face:\" fields are present. The +display of the images requires \"wget\" (see URL +`http://www.gnu.org/software/wget/wget.html'), \"fetch\", or \"curl\" to fetch +the image and the \"convert\" program from the ImageMagick suite (see URL `http://www.imagemagick.org/'). Of the three header fields this is the most efficient in terms of network usage since the image doesn't need to be transmitted with every single mail. -The option `mh-fetch-x-image-url' controls the fetching of the `X-Image-URL:' -header field image." +The option `mh-fetch-x-image-url' controls the fetching of the +\"X-Image-URL:\" header field image." :type 'boolean :group 'mh-show) (defcustom mh-store-default-directory nil - "*Last directory used by \\[mh-store-msg]; default for next store. -A directory name string, or nil to use current directory." + "*Default directory for \\\\[mh-store-msg]. + +If you would like to change the initial default directory, customize this +option, change the value from `Current' to `Directory', and then enter the +name of the directory for storing the content of these messages." :type '(choice (const :tag "Current" nil) directory) :group 'mh-show) (defcustom mh-summary-height nil - "*Number of lines in MH-Folder window (including the mode line)." + "*Number of lines in MH-Folder buffer (including the mode line). + +The default value of this option is \"Automatic\" which means that the +MH-Folder buffer will maintain the same proportional size if the frame is +resized. If you'd prefer a fixed height, then choose the \"Fixed Size\" option +and enter the number of lines you'd like to see." :type '(choice (const :tag "Automatic" nil) - (integer :tag "Fixed sized")) + (integer :tag "Fixed Size")) :group 'mh-show) -(defcustom mhl-formfile nil - "*Name of format file to be used by mhl to show and print messages. -A value of t means use the default format file. -nil means don't use mhl to format messages when showing; mhl is still used, -with the default format file, to format messages when printing them. -The format used should specify a non-zero value for overflowoffset so -the message continues to conform to RFC 822 and MH-E can parse the headers." - :type '(choice (const nil) (const t) string) - :group 'mh-show) -(put 'mhl-formfile 'info-file "mh-e") - ;;; The Speedbar (:group 'mh-speed) -(defcustom mh-large-folder 200 - "The number of messages that indicates a large folder. -If a folder is deemed to be large, that is the number of messages in it exceed -this value, then confirmation is needed when it is visited. Even when -`mh-show-threads-flag' is non-nil, the folder is not automatically threaded, if -it is large. If set to nil all folders are treated as if they are small." - :type '(choice (const :tag "No limit") integer) - :group 'mh-speed) - (defcustom mh-speed-flists-interval 60 "Time between calls to flists in seconds. If 0, flists is not called repeatedly." @@ -1657,6 +1788,19 @@ +;;; Threading (:group 'mh-thread) + +(defcustom mh-show-threads-flag nil + "*Non-nil means new folders start in threaded mode. + +Threading large number of messages can be time consuming so this option is +turned off by default. If you turn this option on, then threading will be done +only if the number of messages being threaded is less than `mh-large-folder'." + :type 'boolean + :group 'mh-thread) + + + ;;; The Toolbar (:group 'mh-toolbar) (defcustom mh-tool-bar-search-function 'mh-search-folder @@ -2119,7 +2263,7 @@ See also `mh-quit-hook'." :type 'hook :group 'mh-hooks - :group 'mh-show) + :group 'mh-folder) (defcustom mh-before-send-letter-hook nil "Invoked at the beginning of the \\\\[mh-send-letter] command. @@ -2131,7 +2275,10 @@ :group 'mh-letter) (defcustom mh-delete-msg-hook nil - "Invoked after marking each message for deletion." + "Invoked after marking each message for deletion. + +For example, a past maintainer of MH-E used this once when he kept statistics +on his mail usage." :type 'hook :group 'mh-hooks :group 'mh-show) @@ -2146,13 +2293,13 @@ "Invoked by `mh-find-path' after reading the user's MH profile." :type 'hook :group 'mh-hooks - :group 'mh-show) + :group 'mh-e) (defcustom mh-folder-mode-hook nil "Invoked in `mh-folder-mode' on a new folder." :type 'hook :group 'mh-hooks - :group 'mh-show) + :group 'mh-folder) (defcustom mh-folder-updated-hook nil "Invoked when the folder actions (such as moves and deletes) are performed. @@ -2160,13 +2307,14 @@ `mh-refile-list' which can be used to see which changes are being made to current folder, `mh-current-folder'." :type 'hook - :group 'mh-hooks) + :group 'mh-hooks + :group 'mh-folder) (defcustom mh-forward-hook nil "Invoked on the forwarded letter by \\\\[mh-forward]." :type 'hook :group 'mh-hooks - :group 'mh-folder) + :group 'mh-sending-mail) (defcustom mh-inc-folder-hook nil "Invoked by \\`\\[mh-inc-folder]' after incorporating mail into a folder." @@ -2174,6 +2322,15 @@ :group 'mh-hooks :group 'mh-inc) +(defcustom mh-insert-signature-hook nil + "Invoked after signature has been inserted. + +These functions may access the actual name of the file or the function used to +insert the signature with `mh-signature-file-name'." + :type 'hook + :group 'mh-hooks + :group 'mh-letter) + (defcustom mh-kill-folder-suppress-prompt-hook '(mh-index-p) "Invoked at the beginning of the \\`\\[mh-kill-folder]' command. This hook is a list of functions to be called, with no arguments, which should @@ -2189,15 +2346,7 @@ in the +inbox buffer, you will not be happy." :type 'hook :group 'mh-hooks - :group 'mh-show) - -(defcustom mh-letter-insert-signature-hook nil - "Invoked after signature has been inserted. -This hook may access the actual name of the file or the function used to -insert the signature with `mh-signature-file-name'." - :type 'hook - :group 'mh-hooks - :group 'mh-letter) + :group 'mh-folder) (defcustom mh-letter-mode-hook nil "Invoked by `mh-letter-mode' on a new letter." @@ -2216,22 +2365,28 @@ See also `mh-before-quit-hook'." :type 'hook :group 'mh-hooks - :group 'mh-show) + :group 'mh-folder) (defcustom mh-refile-msg-hook nil "Invoked after marking each message for refiling." :type 'hook :group 'mh-hooks - :group 'mh-show) + :group 'mh-folder) (defcustom mh-show-hook nil - "Invoked after \\`\\[mh-show]' shows a message." + "Invoked after \\\\[mh-show] shows a message. + +It is the last thing called after messages are displayed. It's used to affect +the behavior of MH-E in general or when `mh-show-mode-hook' is too early." :type 'hook :group 'mh-hooks :group 'mh-show) (defcustom mh-show-mode-hook nil - "Invoked upon entry to `mh-show-mode'." + "Invoked upon entry to `mh-show-mode'. + +This hook is called early on in the process of the message display. It is +usually used to perform some action on the message's content." :type 'hook :group 'mh-hooks :group 'mh-show) @@ -2242,7 +2397,7 @@ will be removed from the unseen sequence." :type 'hook :group 'mh-hooks - :group 'mh-show) + :group 'mh-sequences) diff -r 8e25aa911e3e -r 37d0562504bf lisp/mh-e/mh-e.el --- a/lisp/mh-e/mh-e.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mh-e/mh-e.el Sat Dec 10 21:18:28 2005 +0000 @@ -132,7 +132,7 @@ "%<(zero)%17(friendly{from})%> " "%{subject}%<{body}<<%{body}%>") "*Scan format string for MH. -This string is passed to the scan program via the -format arg. +This string is passed to the scan program via the -format argument. This format is identical to the default except that additional hints for fontification have been added to the fifth column (remember that in Emacs, the first column is 0). @@ -186,7 +186,7 @@ parenthesized expression which matches the message number as in the default of \"^\\\\( *[0-9]+\\\\)[^D^0-9]\". This expression includes the leading space within the parenthesis since it looks better to highlight it as well. This -regular expression should be correct as it is needed by non-fontifying +regular expression should be correct as it is needed by non-fontification functions.") (defvar mh-scan-deleted-msg-regexp "^\\( *[0-9]+\\)D" @@ -196,8 +196,8 @@ parenthesized expression which matches the message number as in the default of \"^\\\\( *[0-9]+\\\\)D\". This expression includes the leading space within the parenthesis since it looks better to highlight it as well. This regular -expression should be correct as it is needed by non-fontifying functions. See -also `mh-note-deleted'.") +expression should be correct as it is needed by non-fontification functions. +See also `mh-note-deleted'.") (defvar mh-scan-refiled-msg-regexp "^\\( *[0-9]+\\)\\^" "This regular expression matches refiled messages. @@ -206,7 +206,7 @@ parenthesized expression which matches the message number as in the default of \"^\\\\( *[0-9]+\\\\)\\\\^\". This expression includes the leading space within the parenthesis since it looks better to highlight it as well. This -regular expression should be correct as it is needed by non-fontifying +regular expression should be correct as it is needed by non-fontification functions. See also `mh-note-refiled'.") (defvar mh-scan-valid-regexp "^ *[0-9]" @@ -222,7 +222,7 @@ \"^\\\\( *[0-9]+\\\\+\\\\).*\". This expression includes the leading space and current message marker \"+\" within the parenthesis since it looks better to highlight these items as well. This regular expression should be correct as it -is needed by non-fontifying functions. See also `mh-note-cur'.") +is needed by non-fontification functions. See also `mh-note-cur'.") (defvar mh-scan-date-regexp "\\([0-9][0-9]/[0-9][0-9]\\)" "This regular expression matches a valid date. @@ -262,7 +262,7 @@ ^ *[0-9]+........[ ]*................... \\\\([Rr][Ee]\\\\(\\\\\\=[[0-9]+\\\\]\\\\)?:\\\\s-*\\\\)* \\\\([^<\\n]*\\\\) -This regular expression should be correct as it is needed by non-fontifying +This regular expression should be correct as it is needed by non-fontification functions.") (defvar mh-scan-format-regexp @@ -535,8 +535,15 @@ ;;; User executable MH-E commands: (defun mh-delete-msg (range) - "Mark the specified RANGE for subsequent deletion and move to the next. -Default is the displayed message. + "Delete message\\. + +To mark a message for deletion, use this command. A \"D\" is placed by the +message in the scan window, and the next undeleted message is displayed. If +the previous command had been \\[mh-previous-undeleted-msg], then the next +message displayed is the first undeleted message previous to the message just +deleted. Use \\[mh-next-undeleted-msg] to force subsequent \\[mh-delete-msg] +commands to move forward to the next undeleted message after deleting the +message under the cursor. Check the documentation of `mh-interactive-range' to see how RANGE is read in interactive use." @@ -545,7 +552,10 @@ (if (looking-at mh-scan-deleted-msg-regexp) (mh-next-msg))) (defun mh-delete-msg-no-motion (range) - "Mark the specified RANGE for subsequent deletion. + "Delete RANGE, don't move to next message. + +This command marks the RANGE for deletion but leaves the cursor at the current +message in case you wish to perform other operations on the message. Check the documentation of `mh-interactive-range' to see how RANGE is read in interactive use." @@ -564,24 +574,22 @@ t) ; return t for write-file-functions (defun mh-first-msg () - "Move to the first message." + "Display first message." (interactive) (goto-char (point-min)) (while (and (not (eobp)) (not (looking-at mh-scan-valid-regexp))) (forward-line 1))) (defun mh-header-display () - "Show the current message with all its headers. -Displays headers that might have been suppressed by setting the -variables `mh-clean-message-header-flag' or `mhl-formfile', or by the fallback -behavior of scrolling uninteresting headers off the top of the window. -Type \"\\[mh-show]\" to show the message normally again." + "Display message with all header fields\\. + +Use the command \\[mh-show] to show the message normally again." (interactive) (and (not mh-showing-with-headers) - (or mhl-formfile mh-clean-message-header-flag) + (or mh-mhl-format-file mh-clean-message-header-flag) (mh-invalidate-show-buffer)) (let ((mh-decode-mime-flag nil) - (mhl-formfile nil) + (mh-mhl-format-file nil) (mh-clean-message-header-flag nil)) (mh-show-msg nil) (mh-in-show-buffer (mh-show-buffer) @@ -630,21 +638,26 @@ (run-hooks 'mh-inc-folder-hook))) (defun mh-last-msg () - "Move to the last message." + "Display last message." (interactive) (goto-char (point-max)) (while (and (not (bobp)) (not (looking-at mh-scan-valid-regexp))) (forward-line -1)) (mh-recenter nil)) -(defun mh-next-undeleted-msg (&optional arg wait-after-complaining-flag) - "Move to the next undeleted message ARG in window. -If optional argument WAIT-AFTER-COMPLAINING-FLAG is non-nil and we are at the -last undeleted message then pause for a second after printing message." +(defun mh-next-undeleted-msg (&optional count wait-after-complaining-flag) + "Display next message. + +This command can be given a prefix argument COUNT to specify how many unread +messages to skip. + +In a program, pause for a second after printing message if we are at the last +undeleted message and optional argument WAIT-AFTER-COMPLAINING-FLAG is +non-nil." (interactive "p") (setq mh-next-direction 'forward) (forward-line 1) - (cond ((re-search-forward mh-scan-good-msg-regexp nil t arg) + (cond ((re-search-forward mh-scan-good-msg-regexp nil t count) (beginning-of-line) (mh-maybe-show)) (t (forward-line -1) @@ -730,14 +743,20 @@ t)) (defun mh-refile-msg (range folder &optional dont-update-last-destination-flag) - "Refile RANGE into FOLDER. + "Refile (output) RANGE into FOLDER. + +You are prompted for the folder name. Note that this command can also be used +to create folders. If you specify a folder that does not exist, you will be +prompted to create it. + +The hook `mh-refile-msg-hook' is called after a message is marked to be +refiled. Check the documentation of `mh-interactive-range' to see how RANGE is read in interactive use. -If optional argument DONT-UPDATE-LAST-DESTINATION-FLAG is non-nil then the -variables `mh-last-destination' and `mh-last-destination-folder' are not -updated." +If DONT-UPDATE-LAST-DESTINATION-FLAG is non-nil, then the variables +`mh-last-destination' and `mh-last-destination-folder' are not updated." (interactive (list (mh-interactive-range "Refile") (intern (mh-prompt-for-refile-folder)))) (unless dont-update-last-destination-flag @@ -748,24 +767,27 @@ (when (looking-at mh-scan-refiled-msg-regexp) (mh-next-msg))) (defun mh-refile-or-write-again (range &optional interactive-flag) - "Re-execute the last refile or write command on the given RANGE. -Default is the displayed message. Use the same folder or file as the previous -refile or write command. -If INTERACTIVE-FLAG is non-nil then the function was called interactively." + "Repeat last output command. + +If you are refiling several messages into the same folder, you can use this +command to repeat the last refile or write. You can use a range. + +Check the documentation of `mh-interactive-range' to see how RANGE is read in +interactive use. + +In a program, a non-nil INTERACTIVE-FLAG means that the function was called +interactively." (interactive (list (mh-interactive-range "Redo") t)) (if (null mh-last-destination) (error "No previous refile or write")) - (let (output) - (setq output - (cond ((eq (car mh-last-destination) 'refile) - (mh-refile-msg range (cdr mh-last-destination)) - (format "Destination folder: %s" (cdr mh-last-destination))) - (t - (mh-iterate-on-range msg range - (apply 'mh-write-msg-to-file msg (cdr mh-last-destination))) - (mh-next-msg interactive-flag) - (format "Destination: %s" (cdr mh-last-destination))))) - (message "%s" output))) + (cond ((eq (car mh-last-destination) 'refile) + (mh-refile-msg range (cdr mh-last-destination)) + (message "%s" (format "Destination folder: %s" + (cdr mh-last-destination)))) + (t + (mh-iterate-on-range msg range + (apply 'mh-write-msg-to-file msg (cdr mh-last-destination))) + (mh-next-msg interactive-flag)))) (defun mh-quit () "Quit the current MH-E folder. @@ -795,11 +817,12 @@ (set-window-configuration mh-previous-window-config)) (run-hooks 'mh-quit-hook)) -(defun mh-page-msg (&optional arg) - "Page the displayed message forwards. -Scrolls ARG lines or a full screen if no argument is supplied. Show buffer -first if not displayed. Show the next undeleted message if looking at the -bottom of the current message." +(defun mh-page-msg (&optional lines) + "Display next page in message. + +You can give this command a prefix argument that specifies the number of LINES +to scroll. This command will also show the next undeleted message if it is +used at the bottom of a message." (interactive "P") (if mh-showing-mode (if mh-page-to-next-msg-flag @@ -816,32 +839,40 @@ "previous" "next")) (setq mh-page-to-next-msg-flag t)) - (scroll-other-window arg))) + (scroll-other-window lines))) (mh-show))) -(defun mh-previous-page (&optional arg) - "Page the displayed message backwards. -Scrolls ARG lines or a full screen if no argument is supplied." +(defun mh-previous-page (&optional lines) + "Display next page in message. + +You can give this command a prefix argument that specifies the number of LINES +to scroll." (interactive "P") (mh-in-show-buffer (mh-show-buffer) - (scroll-down arg))) + (scroll-down lines))) + +(defun mh-previous-undeleted-msg (&optional count wait-after-complaining-flag) + "Display previous message. -(defun mh-previous-undeleted-msg (&optional arg wait-after-complaining-flag) - "Move to the previous undeleted message ARG in window. -If optional argument WAIT-AFTER-COMPLAINING-FLAG is non-nil and we are at the -first undeleted message then pause for a second after printing message." +This command can be given a prefix argument COUNT to specify how many unread +messages to skip. + +In a program, pause for a second after printing message if we are at the last +undeleted message and optional argument WAIT-AFTER-COMPLAINING-FLAG is +non-nil." (interactive "p") (setq mh-next-direction 'backward) (beginning-of-line) - (cond ((re-search-backward mh-scan-good-msg-regexp nil t arg) + (cond ((re-search-backward mh-scan-good-msg-regexp nil t count) (mh-maybe-show)) (t (message "No previous undeleted message") (if wait-after-complaining-flag (sit-for 1))))) (defun mh-previous-unread-msg (&optional count) - "Move to previous unread message. -With optional argument COUNT, COUNT-1 unread messages before current message -are skipped." + "Display previous unread message. + +This command can be given a prefix argument COUNT to specify how many unread +messages to skip." (interactive "p") (unless (> count 0) (error "The function mh-previous-unread-msg expects positive argument")) @@ -916,11 +947,13 @@ (point)))) (defun mh-next-button (&optional backward-flag) - "Go to the next MIME button. -Advance point to the next MIME button in the show buffer. If the end -of buffer is reached then the search wraps over to the start of the -buffer. With prefix argument, BACKWARD-FLAG the point will move to the -previous MIME button." + "Go to the next button. + +If the end of the buffer is reached then the search wraps over to the start of +the buffer. + +If an optional prefix argument BACKWARD-FLAG is given, the cursor will move to +the previous button." (interactive (list current-prefix-arg)) (unless mh-showing-mode (mh-show)) @@ -928,10 +961,10 @@ (mh-goto-next-button backward-flag))) (defun mh-prev-button () - "Go to the prev MIME button. -Move point to the previous MIME button in the show buffer. If the beginning -of the buffer is reached then the search wraps over to the end of the -buffer." + "Go to the previous button. + +If the beginning of the buffer is reached then the search wraps over to the +end of the buffer." (interactive) (mh-next-button t)) @@ -969,31 +1002,48 @@ (funcall action))))))) (defun mh-folder-toggle-mime-part (part-index) - "Toggle display of button. -If point in show buffer is at a button then that part is toggled. -If not at a button and PART-INDEX is non-nil point is moved to that part. -With nil PART-INDEX find the first button after point (search wraps around if -end of buffer is reached) and toggle it." + "View attachment. + +This command displays (or hides) the attachment associated with the button +under the cursor. If the cursor is not located over a button, then the cursor +first moves to the next button, wrapping to the beginning of the message if +necessary. This command has the advantage over related commands of working +from the MH-Folder buffer. + +You can also provide a numeric prefix argument PART-INDEX to view the +attachment labeled with that number. If Emacs does not know how to display the +attachment, then Emacs offers to save the attachment in a file." (interactive "P") (when (consp part-index) (setq part-index (car part-index))) (mh-folder-mime-action part-index #'mh-press-button t)) (defun mh-folder-inline-mime-part (part-index) - "Show the raw bytes of MIME part inline. -If point in show buffer is at a mime part then that part is inlined. -If not at a mime-part and PART-INDEX is non-nil point is moved to that part. -With nil PART-INDEX find the first button after point (search wraps around if -end of buffer is reached) and inline it." + "Show attachment verbatim. + +You can view the raw contents of an attachment with this command. This command +displays (or hides) the contents of the attachment associated with the button +under the cursor verbatim. If the cursor is not located over a button, then +the cursor first moves to the next button, wrapping to the beginning of the +message if necessary. + +You can also provide a numeric prefix argument PART-INDEX to view the +attachment labeled with that number." (interactive "P") (when (consp part-index) (setq part-index (car part-index))) (mh-folder-mime-action part-index #'mh-mime-inline-part nil)) (defun mh-folder-save-mime-part (part-index) - "Save MIME part. -If point in show buffer is at a mime part then that part is saved. -If not at a mime-part and PART-INDEX is non-nil point is moved to that part. -With nil PART-INDEX find the first button after point (search wraps around if -end of buffer is reached) and save it." + "Save (output) attachment. + +This command saves the attachment associated with the button under the cursor. +If the cursor is not located over a button, then the cursor first moves to the +next button, wrapping to the beginning of the message if necessary. + +You can also provide a numeric prefix argument PART-INDEX to save the +attachment labeled with that number. + +This command prompts you for a filename and suggests a specific name if it is +available." (interactive "P") (when (consp part-index) (setq part-index (car part-index))) (mh-folder-mime-action part-index #'mh-mime-save-part nil)) @@ -1009,11 +1059,19 @@ (let ((buffer-read-only nil)) (erase-buffer))) (defun mh-rescan-folder (&optional range dont-exec-pending) - "Rescan a folder after optionally processing the outstanding commands. -If optional prefix argument RANGE is provided, prompt for the range of -messages to display. Otherwise show the entire folder. -If optional argument DONT-EXEC-PENDING is non-nil then pending deletes and -refiles aren't carried out." + "Rescan folder\\. + +This command is useful to grab all messages in your \"+inbox\" after +processing your new mail for the first time. If you don't want to rescan the +entire folder, this command will accept a RANGE. Check the documentation of +`mh-interactive-range' to see how RANGE is read in interactive use. + +This command will ask if you want to process refiles or deletes first and then +either run \\[mh-execute-commands] for you or undo the pending refiles and +deletes, which are lost. + +In a program, the processing of outstanding commands is not performed if +DONT-EXEC-PENDING is non-nil." (interactive (list (if current-prefix-arg (mh-read-range "Rescan" mh-current-folder t nil t mh-interpret-number-as-range-flag) @@ -1024,10 +1082,13 @@ (cond (threaded-flag (mh-toggle-threads)) (mh-index-data (mh-index-insert-folder-headers))))) -(defun mh-write-msg-to-file (msg file no-headers) - "Append MSG to the end of a FILE. -If prefix argument NO-HEADERS is provided, write only the message body. -Otherwise send the entire message including the headers." +(defun mh-write-msg-to-file (message file no-header) + "Append MESSAGE to end of FILE\\. + +You are prompted for the filename. If the file already exists, the message is +appended to it. You can also write the message to the file without the header +by specifying a prefix argument NO-HEADER. Subsequent writes to the same file +can be made with the command \\[mh-refile-or-write-again]." (interactive (list (mh-get-msg-num t) (let ((default-dir (if (eq 'write (car mh-last-destination-write)) @@ -1041,16 +1102,16 @@ (car (cdr mh-last-destination-write)) (expand-file-name "mail.out" default-dir)))) current-prefix-arg)) - (let ((msg-file-to-output (mh-msg-filename msg)) + (let ((msg-file-to-output (mh-msg-filename message)) (output-file (mh-expand-file-name file))) - (setq mh-last-destination (list 'write file (if no-headers 'no-headers)) + (setq mh-last-destination (list 'write file (if no-header 'no-header)) mh-last-destination-write mh-last-destination) (save-excursion (set-buffer (get-buffer-create mh-temp-buffer)) (erase-buffer) (insert-file-contents msg-file-to-output) (goto-char (point-min)) - (if no-headers (search-forward "\n\n")) + (if no-header (search-forward "\n\n")) (append-to-file (point) (point-max) output-file)))) (defun mh-toggle-showing () @@ -1061,7 +1122,12 @@ (mh-show))) (defun mh-undo (range) - "Undo the pending deletion or refile of the specified RANGE. + "Undo pending deletes or refiles in RANGE. + +If you've deleted a message or refiled it, but changed your mind, you can +cancel the action before you've executed it. Use this command to undo a refile +on or deletion of a single message. You can also undo refiles and deletes for +messages that are found in a given RANGE. Check the documentation of `mh-interactive-range' to see how RANGE is read in interactive use." @@ -1206,17 +1272,29 @@ (mh-folder-size-folder folder))) (defun mh-visit-folder (folder &optional range index-data) - "Visit FOLDER and display RANGE of messages. -Do not call this function from outside MH-E; see \\[mh-rmail] instead. + "Visit FOLDER. + +When you want to read the messages that you have refiled into folders, use +this command to visit the folder. You are prompted for the folder name. -If RANGE is nil (the default if it is omitted when called non-interactively), -then all messages in FOLDER are displayed. +The folder buffer will show just unseen messages if there are any; otherwise, +it will show all the messages in the buffer as long there are fewer than +`mh-large-folder' messages. If there are more, then you are prompted for a +range of messages to scan. -If an index buffer is being created then INDEX-DATA is used to initialize the -index buffer specific data structures. +You can provide a prefix argument in order to specify a RANGE of messages to +show when you visit the folder. In this case, regions are not used to specify +the range and `mh-large-folder' is ignored. Check the documentation of +`mh-interactive-range' to see how RANGE is read in interactive use. -A prefix argument will cause a prompt for the RANGE of messages -regardless of the size of the `mh-large-folder' variable." +Note that this command can also be used to create folders. If you specify a +folder that does not exist, you will be prompted to create it. + +Do not call this function from outside MH-E; use \\[mh-rmail] instead. + +If, in a program, RANGE is nil (the default), then all messages in FOLDER are +displayed. If an index buffer is being created then INDEX-DATA is used to +initialize the index buffer specific data structures." (interactive (let ((folder-name (mh-prompt-for-folder "Visit" mh-inbox t))) (list folder-name (mh-read-range "Scan" folder-name t nil @@ -1346,8 +1424,10 @@ (mh-previous-undeleted-msg 1 wait-after-complaining-flag))) (defun mh-next-unread-msg (&optional count) - "Move to next unread message. -With optional argument COUNT, COUNT-1 unread messages are skipped." + "Display next unread message. + +This command can be given a prefix argument COUNT to specify how many unread +messages to skip." (interactive "p") (unless (> count 0) (error "The function mh-next-unread-msg expects positive argument")) @@ -1577,7 +1657,7 @@ `:+N' `:-N' Up to N messages beginning with (or ending with) message num. Num may be - any of the pre-defined symbols: first, prev, cur, next or last. + any of the predefined symbols: first, prev, cur, next or last. `first:N' `prev:N' @@ -1668,7 +1748,7 @@ (turn-on-font-lock))) ; Force font-lock in XEmacs. (defun mh-toggle-mime-buttons () - "Toggle display of buttons for inline MIME parts." + "Toggle option `mh-display-buttons-for-inline-parts-flag'." (interactive) (setq mh-display-buttons-for-inline-parts-flag (not mh-display-buttons-for-inline-parts-flag)) @@ -1712,10 +1792,15 @@ '(mh-folder-mode . mh-restore-desktop-buffer))) (defun mh-scan-folder (folder range &optional dont-exec-pending) - "Scan the FOLDER over the RANGE. -If the optional argument DONT-EXEC-PENDING is non-nil then pending deletes and -refiles aren't carried out. -Return in the folder's buffer." + "Scan FOLDER over RANGE. + +After the scan is performed, switch to the buffer associated with FOLDER. + +Check the documentation of `mh-interactive-range' to see how RANGE is read in +interactive use. + +The processing of outstanding commands is not performed if DONT-EXEC-PENDING +is non-nil." (when (stringp range) (setq range (delete "" (split-string range "[ \t\n]")))) (cond ((null (get-buffer folder)) @@ -1754,7 +1839,7 @@ (setq mh-cmd-note column)) (defun mh-regenerate-headers (range &optional update) - "Scan folder over range RANGE. + "Scan folder over RANGE. If UPDATE, append the scan lines, otherwise replace." (let ((folder mh-current-folder) (range (if (and range (atom range)) (list range) range)) @@ -2281,9 +2366,10 @@ msgs)) (defun mh-notate-user-sequences (&optional range) - "Mark user-defined sequences in the messages specified by RANGE. -The optional argument RANGE can be a message number, a list of message -numbers, a sequence, a region in a cons cell. If nil all messages are notated." + "Mark user-defined sequences in RANGE. + +Check the documentation of `mh-interactive-range' to see how RANGE is read in +interactive use; if nil all messages are notated." (unless range (setq range (cons (point-min) (point-max)))) (let ((seqs mh-seq-list) @@ -2316,8 +2402,7 @@ Check the documentation of `mh-interactive-range' to see how RANGE is read in interactive use. -Optional third arg INTERNAL-FLAG non-nil means do not inform MH of the -change." +In a program, non-nil INTERNAL-FLAG means do not inform MH of the change." (interactive (list (mh-interactive-range "Delete") (mh-read-seq-default "Delete from" t) nil)) @@ -2343,9 +2428,9 @@ (apply #'mh-speed-flists t folders-changed))))) (defun mh-catchup (range) - "Delete RANGE from the `mh-unseen-seq' sequence. + "Delete RANGE from the \"unseen\" sequence. -Check the document of `mh-interactive-range' to see how RANGE is read in +Check the documentation of `mh-interactive-range' to see how RANGE is read in interactive use." (interactive (list (mh-interactive-range "Catchup" (cons (point-min) (point-max))))) @@ -2475,14 +2560,11 @@ (gnus-define-keys (mh-ps-print-map "P" mh-folder-mode-map) "?" mh-prefix-help - "A" mh-ps-print-toggle-mime "C" mh-ps-print-toggle-color "F" mh-ps-print-toggle-faces - "M" mh-ps-print-toggle-mime "f" mh-ps-print-msg-file "l" mh-print-msg - "p" mh-ps-print-msg - "s" mh-ps-print-msg-show) + "p" mh-ps-print-msg) (gnus-define-keys (mh-sequence-map "S" mh-folder-mode-map) "'" mh-narrow-to-tick @@ -2569,9 +2651,8 @@ (?F "[l]ist; [v]isit folder;\n" "[n]ew messages; [']ticked messages; [s]earch; [i]ndexed search;\n" "[p]ack; [S]ort; [r]escan; [k]ill") - (?P "PS [p]rint message; [l]non-PS print;\n" - "PS Print [s]how window, message to [f]ile;\n" - "Toggle printing of [M]IME parts, [C]olor, [F]aces") + (?P "[p]rint message to [f]ile; old-style [l]pr printing;\n" + "Toggle printing of [C]olors, [F]aces") (?S "[p]ut message in sequence, [n]arrow, [']narrow to ticked, [w]iden,\n" "[s]equences, [l]ist,\n" "[d]elete message from sequence, [k]ill sequence") diff -r 8e25aa911e3e -r 37d0562504bf lisp/mh-e/mh-funcs.el --- a/lisp/mh-e/mh-funcs.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mh-e/mh-funcs.el Sat Dec 10 21:18:28 2005 +0000 @@ -1,7 +1,7 @@ ;;; mh-funcs.el --- MH-E functions not everyone will use right away ;; Copyright (C) 1993, 1995, -;; 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +;; 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. ;; Author: Bill Wohler ;; Maintainer: Bill Wohler @@ -39,15 +39,6 @@ (mh-require-cl) (require 'mh-e) -;;; Customization - -(defvar mh-sortm-args nil - "Extra arguments to have \\[mh-sort-folder] pass to the \"sortm\" command. -The arguments are passed to sortm if \\[mh-sort-folder] is given a -prefix argument. Normally default arguments to sortm are specified in the -MH profile. -For example, '(\"-nolimit\" \"-textfield\" \"subject\") is a useful setting.") - ;;; Scan Line Formats (defvar mh-note-copied "C" @@ -60,9 +51,19 @@ ;;;###mh-autoload (defun mh-burst-digest () - "Burst apart the current message, which should be a digest. -The message is replaced by its table of contents and the messages from the -digest are inserted into the folder after that message." + "Break up digest into separate messages\\. + +This command uses the MH command \"burst\" to break out each message in the +digest into its own message. Using this command, you can quickly delete +unwanted messages, like this: Once the digest is split up, toggle out of +MH-Folder Show mode with \\[mh-toggle-showing] so that the scan lines fill the +screen and messages aren't displayed. Then use \\[mh-delete-msg] to quickly +delete messages that you don't want to read (based on the \"Subject:\" header +field). You can also burst the digest to reply directly to the people who +posted the messages in the digest. One problem you may encounter is that the +\"From:\" header fields are preceded with a \">\" so that your reply can't +create the \"To:\" field correctly. In this case, you must correct the \"To:\" +field yourself." (interactive) (let ((digest (mh-get-msg-num t))) (mh-process-or-undo-commands mh-current-folder) @@ -78,7 +79,14 @@ ;;;###mh-autoload (defun mh-copy-msg (range folder) - "Copy the specified RANGE to another FOLDER without deleting them. + "Copy RANGE to FOLDER\\. + +If you wish to copy a message to another folder, you can use this command +\(see the \"-link\" argument to \"refile\"). Like the command +\\[mh-refile-msg], this command prompts you for the name of the target folder +and you can specify a range. Note that unlike the command \\[mh-refile-msg], +the copy takes place immediately. The original copy remains in the current +folder. Check the documentation of `mh-interactive-range' to see how RANGE is read in interactive use." @@ -155,10 +163,16 @@ ;;;###mh-autoload (defun mh-pack-folder (range) - "Renumber the messages of a folder to be 1..n. -First, offer to execute any outstanding commands for the current folder. If -optional prefix argument provided, prompt for the RANGE of messages to display -after packing. Otherwise, show the entire folder." + "Pack folder\\. + +This command packs the folder, removing gaps from the numbering sequence. If +you don't want to rescan the entire folder afterward, this command will accept +a RANGE. Check the documentation of `mh-interactive-range' to see how RANGE is +read in interactive use. + +This command will ask if you want to process refiles or deletes first and then +either run \\[mh-execute-commands] for you or undo the pending refiles and +deletes, which are lost." (interactive (list (if current-prefix-arg (mh-read-range "Scan" mh-current-folder t nil t mh-interpret-number-as-range-flag) @@ -174,8 +188,8 @@ (defun mh-pack-folder-1 (range) "Close and pack the current folder. -Display the given RANGE of messages after packing. If RANGE is nil, show the -entire folder." + +Display RANGE after packing, or the entire folder if RANGE is nil." (mh-process-or-undo-commands mh-current-folder) (message "Packing folder...") (mh-set-folder-modified-p t) ; lock folder while packing @@ -186,10 +200,12 @@ (mh-regenerate-headers range)) ;;;###mh-autoload -(defun mh-pipe-msg (command include-headers) - "Pipe the current message through the given shell COMMAND. -If INCLUDE-HEADERS (prefix argument) is provided, send the entire message. -Otherwise just send the message's body without the headers." +(defun mh-pipe-msg (command include-header) + "Pipe message through shell command COMMAND. + +You are prompted for the Unix command through which you wish to run your +message. If you give an argument INCLUDE-HEADER to this command, the message +header is included in the text passed to the command." (interactive (list (read-string "Shell command on message: ") current-prefix-arg)) (let ((msg-file-to-pipe (mh-msg-filename (mh-get-msg-num t))) @@ -199,13 +215,13 @@ (erase-buffer) (insert-file-contents msg-file-to-pipe) (goto-char (point-min)) - (if (not include-headers) (search-forward "\n\n")) + (if (not include-header) (search-forward "\n\n")) (let ((default-directory message-directory)) (shell-command-on-region (point) (point-max) command nil))))) ;;;###mh-autoload (defun mh-page-digest () - "Advance displayed message to next digested message." + "Display next message in digest." (interactive) (mh-in-show-buffer (mh-show-buffer) ;; Go to top of screen (in case user moved point). @@ -222,7 +238,7 @@ ;;;###mh-autoload (defun mh-page-digest-backwards () - "Back up displayed message to previous digested message." + "Display previous message in digest." (interactive) (mh-in-show-buffer (mh-show-buffer) ;; Go to top of screen (in case user moved point). @@ -274,10 +290,13 @@ ;;;###mh-autoload (defun mh-store-msg (directory) - "Store the file(s) contained in the current message into DIRECTORY. -The message can contain a shar file or uuencoded file. -Default directory is the last directory used, or initially the value of -`mh-store-default-directory' or the current directory." + "Unpack message created with `uudecode' or `shar'. + +The default DIRECTORY for extraction is the current directory; however, you +have a chance to specify a different extraction directory. The next time you +use this command, the default directory is the last directory you used. If you +would like to change the initial default directory, customize the option +`mh-store-default-directory'." (interactive (list (let ((udir (or mh-store-default-directory default-directory))) (read-file-name "Store message in directory: " diff -r 8e25aa911e3e -r 37d0562504bf lisp/mh-e/mh-index.el --- a/lisp/mh-e/mh-index.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mh-e/mh-index.el Sat Dec 10 21:18:28 2005 +0000 @@ -1287,12 +1287,12 @@ (defun mh-index-sequenced-messages (folders sequence) "Display messages from FOLDERS in SEQUENCE. All messages in the sequence you provide from the folders in -`mh-index-new-messages-folders' are listed. With a prefix argument, enter a +`mh-new-messages-folders' are listed. With a prefix argument, enter a space-separated list of folders, or nothing to search all folders." (interactive (list (if current-prefix-arg - (split-string (read-string "Search folder(s): [all] ")) - mh-index-new-messages-folders) + (split-string (read-string "Search folder(s) (default all): ")) + mh-new-messages-folders) (mh-read-seq-default "Search" nil))) (unless sequence (setq sequence mh-unseen-seq)) (let* ((mh-flists-search-folders folders) @@ -1330,27 +1330,33 @@ ;;;###mh-autoload (defun mh-index-new-messages (folders) "Display unseen messages. + If you use a program such as `procmail' to use `rcvstore' to file your incoming mail automatically, you can display new, unseen, messages using this command. All messages in the `unseen' sequence from the folders in -`mh-index-new-messages-folders' are listed. With a prefix argument, enter a -space-separated list of FOLDERS, or nothing to search all folders." +`mh-new-messages-folders' are listed. + +With a prefix argument, enter a space-separated list of FOLDERS, or nothing to +search all folders." (interactive (list (if current-prefix-arg - (split-string (read-string "Search folder(s): [all] ")) - mh-index-new-messages-folders))) + (split-string (read-string "Search folder(s) (default all): ")) + mh-new-messages-folders))) (mh-index-sequenced-messages folders mh-unseen-seq)) ;;;###mh-autoload (defun mh-index-ticked-messages (folders) "Display ticked messages. -All messages in `mh-tick-seq' from the folders in -`mh-index-ticked-messages-folders' are listed. With a prefix argument, enter a -space-separated list of FOLDERS, or nothing to search all folders." + +All messages in `mh-tick-seq' from the folders in `mh-ticked-messages-folders' +are listed. + +With a prefix argument, enter a space-separated list of FOLDERS, or nothing to +search all folders." (interactive (list (if current-prefix-arg - (split-string (read-string "Search folder(s): [all] ")) - mh-index-ticked-messages-folders))) + (split-string (read-string "Search folder(s) (default all): ")) + mh-ticked-messages-folders))) (mh-index-sequenced-messages folders mh-tick-seq)) diff -r 8e25aa911e3e -r 37d0562504bf lisp/mh-e/mh-init.el --- a/lisp/mh-e/mh-init.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mh-e/mh-init.el Sat Dec 10 21:18:28 2005 +0000 @@ -1,6 +1,6 @@ ;;; mh-init.el --- MH-E initialization. -;; Copyright (C) 2003, 2004 Free Software Foundation, Inc. +;; Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. ;; Author: Peter S. Galbraith ;; Maintainer: Bill Wohler @@ -336,7 +336,7 @@ "Non-nil means defface supports min-colors display requirement.") (defun mh-defface-compat (spec) - "Converts SPEC for defface if necessary to run on older platforms. + "Convert SPEC for defface if necessary to run on older platforms. See `defface' for the spec definition. When `mh-min-colors-defined-flag' is nil, this function finds a display with a @@ -354,7 +354,7 @@ (when (not (eq (car entry) t)) (if (assoc 'min-colors (car entry)) (delq (assoc 'min-colors (car entry)) (car entry))))))) - + (provide 'mh-init) ;;; Local Variables: diff -r 8e25aa911e3e -r 37d0562504bf lisp/mh-e/mh-junk.el --- a/lisp/mh-e/mh-junk.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mh-e/mh-junk.el Sat Dec 10 21:18:28 2005 +0000 @@ -41,9 +41,12 @@ (defun mh-junk-blacklist (range) "Blacklist RANGE as spam. -This command trains the spam program in use (see the `mh-junk-program' option) -with the content of the range (see `mh-interactive-range') and then handles -the message(s) as specified by the `mh-junk-disposition' option. +This command trains the spam program in use (see the option `mh-junk-program') +with the content of RANGE and then handles the message(s) as specified by the +option `mh-junk-disposition'. + +Check the documentation of `mh-interactive-range' to see how RANGE is read in +interactive use. For more information about using your particular spam fighting program, see: @@ -77,11 +80,12 @@ (defun mh-junk-whitelist (range) "Whitelist RANGE as ham. -This command reclassifies a range of messages (see `mh-interactive-range') as -ham if it were incorrectly classified as spam. It then refiles the message -into the `+inbox' folder. +This command reclassifies the RANGE as ham if it were incorrectly classified +as spam (see the option `mh-junk-program'). It then refiles the message into +the \"+inbox\" folder. -The `mh-junk-program' option specifies the spam program in use." +Check the documentation of `mh-interactive-range' to see how RANGE is read in +interactive use." (interactive (list (mh-interactive-range "Whitelist"))) (let ((whitelist-func (nth 2 (assoc mh-junk-choice mh-junk-function-alist)))) (unless whitelist-func @@ -306,7 +310,7 @@ (defvar mh-bogofilter-executable (executable-find "bogofilter")) (defun mh-bogofilter-blacklist (msg) - "Blacklist MSG with Bogofilter. + "Blacklist MSG with bogofilter. Bogofilter is a Bayesian spam filtering program. Get it from your local distribution or from http://bogofilter.sourceforge.net/. @@ -324,11 +328,11 @@ Note that most Bayesian filters need 1000 to 5000 of each type of message to start doing a good job. -To use Bogofilter, add the following recipes to `.procmailrc': +To use bogofilter, add the following recipes to `.procmailrc': MAILDIR=$HOME/`mhparam Path` - # Fight spam with Bogofilter. + # Fight spam with bogofilter. :0fw | bogofilter -3 -e -p @@ -340,9 +344,9 @@ * ^X-Bogosity: Unsure, tests=bogofilter spam/unsure/. -If Bogofilter classifies a message incorrectly, or is unsure, you can use the +If bogofilter classifies a message incorrectly, or is unsure, you can use the MH-E commands \\[mh-junk-blacklist] and \\[mh-junk-whitelist] to update -Bogofilter's training. +bogofilter's training. The \"Bogofilter FAQ\" suggests that you run the following occasionally to shrink the database: @@ -359,7 +363,7 @@ nil "-s"))) (defun mh-bogofilter-whitelist (msg) - "Whitelist MSG with Bogofilter. + "Whitelist MSG with bogofilter. See `mh-bogofilter-blacklist' for more information." (unless mh-bogofilter-executable diff -r 8e25aa911e3e -r 37d0562504bf lisp/mh-e/mh-mime.el --- a/lisp/mh-e/mh-mime.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mh-e/mh-mime.el Sat Dec 10 21:18:28 2005 +0000 @@ -799,11 +799,15 @@ Set from last use.") ;;;###mh-autoload -(defun mh-mime-save-parts (arg) - "Store the MIME parts of the current message. -If ARG, prompt for directory, else use that specified by the variable -`mh-mime-save-parts-default-directory'. These directories may be superseded by -MH profile components, since this function calls on mhstore to do the work." +(defun mh-mime-save-parts (prompt) + "Save attachments. + +You can save all of the attachments at once with this command. The attachments +are saved in the directory specified by the option +`mh-mime-save-parts-default-directory' unless you use a prefix argument PROMPT +in which case you are prompted for the directory. These directories may be +superseded by MH profile components, since this function calls on +\"mhstore\" (\"mhn\") to do the work." (interactive "P") (let ((msg (if (eq major-mode 'mh-show-mode) (mh-show-buffer-message-number) @@ -814,12 +818,12 @@ (command (if (mh-variant-p 'nmh) "mhstore" "mhn")) (directory (cond - ((and (or arg + ((and (or prompt (equal nil mh-mime-save-parts-default-directory) (equal t mh-mime-save-parts-default-directory)) (not mh-mime-save-parts-directory)) (read-file-name "Store in directory: " nil nil t nil)) - ((and (or arg + ((and (or prompt (equal t mh-mime-save-parts-default-directory)) mh-mime-save-parts-directory) (read-file-name (format @@ -877,11 +881,13 @@ ;;;###mh-autoload (defun mh-toggle-mh-decode-mime-flag () - "Toggle whether MH-E should decode MIME or not." + "Toggle the value of `mh-decode-mime-flag'." (interactive) (setq mh-decode-mime-flag (not mh-decode-mime-flag)) (mh-show nil t) - (message "(setq mh-decode-mime-flag %s)" mh-decode-mime-flag)) + (message "%s" (if mh-decode-mime-flag + "Processing attachments normally" + "Displaying raw message"))) ;;;###mh-autoload (defun mh-decode-message-header () @@ -1184,7 +1190,7 @@ (goto-char (point-min)) (delete-char 1)) (when (equal (mm-handle-media-supertype handle) "text") - (when (eq mh-highlight-citation-p 'gnus) + (when (eq mh-highlight-citation-style 'gnus) (mh-gnus-article-highlight-citation)) (mh-display-smileys) (mh-display-emphasis) @@ -1205,9 +1211,10 @@ ;;;###mh-autoload (defun mh-press-button () - "Press MIME button. -If the MIME part is visible then it is removed. Otherwise the part is -displayed." + "View contents of button. + +This command is a toggle so if you use it again on the same attachment, the +attachment is hidden." (interactive) (let ((mm-inline-media-tests mh-mm-inline-media-tests) (data (get-text-property (point) 'mh-data)) @@ -1279,7 +1286,23 @@ ;;;###mh-autoload (defun mh-display-with-external-viewer (part-index) - "View MIME PART-INDEX externally." + "View attachment externally. + +If Emacs does not know how to view an attachment, you could save it into a +file and then run some program to open it. It is easier, however, to launch +the program directly from MH-E with this command. While you'll most likely use +this to view spreadsheets and documents, it is also useful to use your browser +to view HTML attachments with higher fidelity than what Emacs can provide. + +This command displays the attachment associated with the button under the +cursor. If the cursor is not located over a button, then the cursor first +moves to the next button, wrapping to the beginning of the message if +necessary. You can provide a numeric prefix argument PART-INDEX to view the +attachment labeled with that number. + +This command tries to provide a reasonable default for the viewer by calling +the Emacs function `mailcap-mime-info'. This function usually reads the file +\"/etc/mailcap\"." (interactive "P") (when (consp part-index) (setq part-index (car part-index))) (mh-folder-mime-action @@ -1290,7 +1313,9 @@ (methods (mapcar (lambda (x) (list (cdr (assoc 'viewer x)))) (mailcap-mime-info type 'all))) (def (caar methods)) - (prompt (format "Viewer: %s" (if def (format "[%s] " def) ""))) + (prompt (format "Viewer%s: " (if def + (format " (default %s)" def) + ""))) (method (completing-read prompt methods nil nil nil nil def)) (folder mh-show-folder-buffer) (buffer-read-only nil)) @@ -1464,7 +1489,7 @@ (mh-decode-message-header) (mh-show-addr) ;; The other highlighting types don't need anything special - (when (eq mh-highlight-citation-p 'gnus) + (when (eq mh-highlight-citation-style 'gnus) (mh-gnus-article-highlight-citation)) (goto-char (point-min)) (insert "\n------- Forwarded Message\n\n") diff -r 8e25aa911e3e -r 37d0562504bf lisp/mh-e/mh-print.el --- a/lisp/mh-e/mh-print.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mh-e/mh-print.el Sat Dec 10 21:18:28 2005 +0000 @@ -25,13 +25,6 @@ ;; Boston, MA 02110-1301, USA. ;;; Commentary: -;; Pp Print to lpr | Default inline settings -;; Pf Print to file | Generate a postscript file -;; Ps Print show buffer | Fails if no show buffer -;; -;; PA Toggle inline/attachments -;; PC Toggle color -;; PF Toggle faces ;;; Change Log: @@ -44,125 +37,121 @@ (require 'mh-funcs) (eval-when-compile (require 'mh-seq)) -(defvar mh-ps-print-mime nil - "Control printing of MIME parts. -The three possible states are: - 1. nil to not print inline parts - 2. t to print inline parts - 3. non-zero to print inline parts and attachments") +(defvar mh-ps-print-color-option ps-print-color-p + "Specify how buffer's text color is printed. + +Valid values are: -(defvar mh-ps-print-color-option ps-print-color-p - "MH-E's version of `\\[ps-print-color-p]'.") + nil - Do not print colors. + t - Print colors. + black-white - Print colors on black/white printer. + See also `ps-black-white-faces'. + +Any other value is treated as t. This variable is initialized from +`ps-print-color-p'.") (defvar mh-ps-print-func 'ps-spool-buffer-with-faces "Function to use to spool a buffer. + Sensible choices are the functions `ps-spool-buffer' and `ps-spool-buffer-with-faces'.") -;; XXX - If buffer is already being displayed, use that buffer -;; XXX - What about showing MIME content? -;; XXX - Default print buffer is bogus (defun mh-ps-spool-buffer (buffer) - "Send BUFFER to printer queue." + "Spool BUFFER." (save-excursion (set-buffer buffer) (let ((ps-print-color-p mh-ps-print-color-option) - (ps-left-header - (list - (concat "(" - (mh-get-header-field "Subject:") ")") - (concat "(" - (mh-get-header-field "From:") ")"))) - (ps-right-header - (list - "/pagenumberstring load" - (concat "(" - (mh-get-header-field "Date:") ")")))) - (funcall mh-ps-print-func)))) + (ps-left-header + (list + (concat "(" (mh-get-header-field "Subject:") ")") + (concat "(" (mh-get-header-field "From:") ")"))) + (ps-right-header + (list + "/pagenumberstring load" + (concat "(" (mh-get-header-field "Date:") ")")))) + (funcall mh-ps-print-func)))) -(defun mh-ps-spool-a-msg (msg buffer) - "Print MSG. -First the message is decoded in BUFFER before the results are sent to the -printer." - (let ((mh-show-buffer mh-show-buffer) - (folder mh-current-folder) - ;; The following is commented out because - ;; `clean-message-header-flag' isn't used anywhere. I - ;; commented rather than deleted in case somebody had some - ;; future plans for it. --SY. - ;(clean-message-header-flag mh-clean-message-header-flag) - ) +(defun mh-ps-spool-msg (msg) + "Spool MSG." + (let* ((folder mh-current-folder) + (buffer (mh-in-show-buffer (mh-show-buffer) + (if (not (equal (mh-msg-filename msg folder) + buffer-file-name)) + (get-buffer-create mh-temp-buffer))))) (unwind-protect - (progn - (setq mh-show-buffer buffer) - (save-excursion - ;; - ;; XXX - Use setting of mh-ps-print-mime - ;; - (mh-display-msg msg folder) - (mh-ps-spool-buffer mh-show-buffer) - (kill-buffer mh-show-buffer)))))) + (save-excursion + (if buffer + (let ((mh-show-buffer buffer)) + (mh-display-msg msg folder))) + (mh-ps-spool-buffer (if buffer buffer mh-show-buffer))) + (if buffer + (kill-buffer buffer))))) + +(defun mh-ps-print-range (range file) + "Print RANGE to FILE. + +This is the function that actually does the work. +If FILE is nil, then the messages are spooled to the printer." + (mh-iterate-on-range msg range + (unwind-protect + (mh-ps-spool-msg msg)) + (mh-notate msg mh-note-printed mh-cmd-note)) + (ps-despool file)) + +(defun mh-ps-print-preprint (prefix-arg) + "Provide a better default file name for `ps-print-preprint'. +Pass along the PREFIX-ARG to it." + (let ((buffer-file-name (format "mh-%s" (substring (buffer-name) 1)))) + (ps-print-preprint prefix-arg))) ;;;###mh-autoload (defun mh-ps-print-msg (range) - "Print the messages in RANGE. - -Check the documentation of `mh-interactive-range' to see how RANGE is read in -interactive use." - (interactive (list (mh-interactive-range "Print"))) - (mh-iterate-on-range msg range - (let ((buffer (get-buffer-create mh-temp-buffer))) - (unwind-protect - (mh-ps-spool-a-msg msg buffer) - (kill-buffer buffer))) - (mh-notate nil mh-note-printed mh-cmd-note)) - (ps-despool nil)) - -(defun mh-ps-print-preprint (prefix-arg) - "Replacement for `ps-print-preprint'. -The original function does not handle the fact that MH folders are directories -nicely, when generating the default file name. This function works around -that. The function is passed the interactive PREFIX-ARG." - (let ((buffer-file-name (format "/tmp/%s" (substring (buffer-name) 1)))) - (ps-print-preprint prefix-arg))) - -;;;###mh-autoload -(defun mh-ps-print-msg-file (file range) - "Print to FILE the messages in RANGE. + "Print RANGE\\. Check the documentation of `mh-interactive-range' to see how RANGE is read in -interactive use." - (interactive (list - (mh-ps-print-preprint 1) - (mh-interactive-range "Print"))) - (mh-iterate-on-range msg range - (let ((buffer (get-buffer-create mh-temp-buffer))) - (unwind-protect - (mh-ps-spool-a-msg msg buffer) - (kill-buffer buffer))) - (mh-notate nil mh-note-printed mh-cmd-note)) - (ps-despool file)) +interactive use. + +This command will print inline text attachments but will not decrypt messages. +However, when a message is displayed in an MH-Show buffer, then that buffer is +used verbatim for printing with the caveat that only text attachments, if +opened inline, are printed. Therefore, encrypted messages can be printed by +showing and decrypting them first. + +MH-E uses the \"ps-print\" package to do the printing, so you can customize +the printing further by going to the `ps-print' customization group. This +command does not use the options `mh-lpr-command-format' or +`mh-print-background-flag'. See also the commands \\[mh-ps-print-toggle-color] +and \\[mh-ps-print-toggle-faces]." + (interactive (list (mh-interactive-range "Print"))) + (mh-ps-print-range range nil)) ;;;###mh-autoload -(defun mh-ps-print-msg-show (file) - "Print current show buffer to FILE." - (interactive (list (mh-ps-print-preprint current-prefix-arg))) - (let ((msg (mh-get-msg-num t)) - (folder mh-current-folder) - (show-buffer mh-show-buffer) - (show-window (get-buffer-window mh-show-buffer))) - (if (and show-buffer show-window) - (mh-in-show-buffer (show-buffer) - (if (equal (mh-msg-filename msg folder) buffer-file-name) - (progn - (mh-ps-spool-buffer show-buffer) - (ps-despool file)) - (message "Current message is not being shown(1)"))) - (message "Current message is not being shown(2)")))) +(defun mh-ps-print-msg-file (range file) + "Print RANGE to FILE\\. + +Check the documentation of `mh-interactive-range' to see how RANGE is read in +interactive use. + +This command will print inline text attachments but will not decrypt messages. +However, when a message is displayed in an MH-Show buffer, then that buffer is +used verbatim for printing with the caveat that only text attachments, if +opened inline, are printed. Therefore, encrypted messages can be printed by +showing and decrypting them first. + +MH-E uses the \"ps-print\" package to do the printing, so you can customize +the printing further by going to the `ps-print' customization group. This +command does not use the options `mh-lpr-command-format' or +`mh-print-background-flag'. See also the commands \\[mh-ps-print-toggle-color] +and \\[mh-ps-print-toggle-faces]." + (interactive (list (mh-interactive-range "Print") (mh-ps-print-preprint 1))) + (mh-ps-print-range range file)) ;;;###mh-autoload (defun mh-ps-print-toggle-faces () - "Toggle whether printing is done with faces or not." + "Toggle whether printing is done with faces or not. + +When faces are enabled, the printed message will look very similar to the +message in the MH-Show buffer." (interactive) (if (eq mh-ps-print-func 'ps-spool-buffer-with-faces) (progn @@ -173,7 +162,15 @@ ;;;###mh-autoload (defun mh-ps-print-toggle-color () - "Toggle whether color is used in printing messages." + "Toggle whether color is used in printing messages. + +Colors are emulated on black-and-white printers with shades of gray. This +might produce illegible output, even if your screen colors only use shades of +gray. If this is the case, try using this command to toggle between color, no +color, and a black and white representation of the colors and see which works +best. You change this setting permanently by customizing the option +`ps-print-color-p'." + (interactive) (if (eq mh-ps-print-color-option nil) (progn @@ -186,36 +183,18 @@ (setq mh-ps-print-color-option nil) (message "Colors will not be printed")))) -;;; XXX: Check option 3. Documentation doesn't sound right. -;;;###mh-autoload -(defun mh-ps-print-toggle-mime () - "Cycle through available choices on how MIME parts should be printed. -The available settings are: - 1. Print only inline MIME parts. - 2. Print all MIME parts. - 3. Print no MIME parts." - (interactive) - (if (eq mh-ps-print-mime nil) - (progn - (setq mh-ps-print-mime t) - (message "Inline parts will be printed, attachments will not be printed")) - (if (eq mh-ps-print-mime t) - (progn - (setq mh-ps-print-mime 1) - (message "Both Inline parts and attachments will be printed")) - (setq mh-ps-print-mime nil) - (message "Neither inline parts nor attachments will be printed")))) - ;;; Old non-PS based printing ;;;###mh-autoload (defun mh-print-msg (range) - "Print RANGE on printer. + "Print RANGE the old fashioned way\\. + +The message is formatted with \"mhl\" (see option `mh-mhl-format-file') and +printed with the \"lpr\" command (see option `mh-lpr-command-format'). Check the documentation of `mh-interactive-range' to see how RANGE is read in interactive use. -The variable `mh-lpr-command-format' is used to generate the print command. -The messages are formatted by mhl. See the variable `mhl-formfile'." +Consider using \\[mh-ps-print-msg] instead." (interactive (list (mh-interactive-range "Print"))) (message "Printing...") (let (msgs) @@ -247,8 +226,8 @@ (dolist (msg msgs) (let* ((mhl-command (format "%s %s %s" (expand-file-name "mhl" mh-lib-progs) - (if mhl-formfile - (format " -form %s" mhl-formfile) + (if mh-mhl-format-file + (format " -form %s" mh-mhl-format-file) "") (mh-msg-filename msg))) (lpr-command diff -r 8e25aa911e3e -r 37d0562504bf lisp/mh-e/mh-seq.el --- a/lisp/mh-e/mh-seq.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mh-e/mh-seq.el Sat Dec 10 21:18:28 2005 +0000 @@ -273,10 +273,16 @@ ;;;###mh-autoload (defun mh-put-msg-in-seq (range sequence) - "Add RANGE to SEQUENCE. + "Add RANGE to SEQUENCE\\. -Check the documentation of `mh-interactive-range' to see how RANGE is read in -interactive use." +To place a message in a sequence, use this command to do it manually, or use +the MH command \"pick\" or the MH-E version of \"pick\", \\[mh-search-folder], +which create a sequence automatically. + +Give this command a RANGE and you can add all the messages in a sequence to +another sequence (for example, \"\\[universal-argument] \\[mh-put-msg-in-seq] +SourceSequence RET DestSequence RET\"). Check the documentation of +`mh-interactive-range' to see how RANGE is read in interactive use." (interactive (list (mh-interactive-range "Add messages from") (mh-read-seq-default "Add to" nil))) (unless (mh-valid-seq-p sequence) @@ -661,8 +667,9 @@ ;;;###mh-autoload (defun mh-range-to-msg-list (range) "Return a list of messages for RANGE. -RANGE can be a message number, a list of message numbers, a sequence, or -a region in a cons cell." + +Check the documentation of `mh-interactive-range' to see how RANGE is read in +interactive use." (let (msg-list) (mh-iterate-on-range msg range (push msg msg-list)) @@ -915,7 +922,7 @@ ;;;###mh-autoload (defun mh-narrow-to-range (range) - "Limit to messages in RANGE. + "Limit to RANGE. Check the documentation of `mh-interactive-range' to see how RANGE is read in interactive use. @@ -1679,7 +1686,7 @@ ;;;###mh-autoload (defun mh-toggle-tick (range) - "Toggle tick mark of all messages in RANGE. + "Toggle tick mark of RANGE. This command adds messages to the \"tick\" sequence (which you can customize via the option `mh-tick-seq'). This sequence can be viewed later with the diff -r 8e25aa911e3e -r 37d0562504bf lisp/mh-e/mh-utils.el --- a/lisp/mh-e/mh-utils.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/mh-e/mh-utils.el Sat Dec 10 21:18:28 2005 +0000 @@ -414,10 +414,11 @@ (defun mh-show-font-lock-fontify-region (beg end loudly) "Limit font-lock in `mh-show-mode' to the header. -Used when `mh-highlight-citation-p' is set to \"'gnus\", leaving the body to -be dealt with by gnus highlighting. The region between BEG and END is given -over to be fontified and LOUDLY controls if a user sees a message about the -fontification operation." + +Used when the option `mh-highlight-citation-style' is set to \"Gnus\", leaving +the body to be dealt with by Gnus highlighting. The region between BEG and END +is given over to be fontified and LOUDLY controls if a user sees a message +about the fontification operation." (let ((header-end (mh-mail-header-end))) (cond ((and (< beg header-end)(< end header-end)) @@ -874,12 +875,10 @@ (mh-defun-show-buffer mh-show-index-sequenced-messages mh-index-sequenced-messages) (mh-defun-show-buffer mh-show-catchup mh-catchup) -(mh-defun-show-buffer mh-show-ps-print-toggle-mime mh-ps-print-toggle-mime) (mh-defun-show-buffer mh-show-ps-print-toggle-color mh-ps-print-toggle-color) (mh-defun-show-buffer mh-show-ps-print-toggle-faces mh-ps-print-toggle-faces) (mh-defun-show-buffer mh-show-ps-print-msg-file mh-ps-print-msg-file) (mh-defun-show-buffer mh-show-ps-print-msg mh-ps-print-msg) -(mh-defun-show-buffer mh-show-ps-print-msg-show mh-ps-print-msg-show) (mh-defun-show-buffer mh-show-toggle-mime-buttons mh-toggle-mime-buttons) (mh-defun-show-buffer mh-show-display-with-external-viewer mh-display-with-external-viewer) @@ -962,14 +961,11 @@ (gnus-define-keys (mh-show-ps-print-map "P" mh-show-mode-map) "?" mh-prefix-help - "A" mh-show-ps-print-toggle-mime "C" mh-show-ps-print-toggle-color "F" mh-show-ps-print-toggle-faces - "M" mh-show-ps-print-toggle-mime "f" mh-show-ps-print-msg-file "l" mh-show-print-msg - "p" mh-show-ps-print-msg - "s" mh-show-ps-print-msg-show) + "p" mh-show-ps-print-msg) (gnus-define-keys (mh-show-thread-map "T" mh-show-mode-map) "?" mh-prefix-help @@ -1110,9 +1106,9 @@ (make-local-variable 'font-lock-defaults) ;;(set (make-local-variable 'font-lock-support-mode) nil) (cond - ((equal mh-highlight-citation-p 'font-lock) + ((equal mh-highlight-citation-style 'font-lock) (setq font-lock-defaults '(mh-show-font-lock-keywords-with-cite t))) - ((equal mh-highlight-citation-p 'gnus) + ((equal mh-highlight-citation-style 'gnus) (setq font-lock-defaults '((mh-show-font-lock-keywords) t nil nil nil (font-lock-fontify-region-function @@ -1258,7 +1254,7 @@ (defun mh-show-xface () "Display X-Face." (when (and window-system mh-show-use-xface-flag - (or mh-decode-mime-flag mhl-formfile + (or mh-decode-mime-flag mh-mhl-format-file mh-clean-message-header-flag)) (funcall mh-show-xface-function))) @@ -1560,24 +1556,24 @@ (if mh-showing-mode (mh-show msg))) (defun mh-show (&optional message redisplay-flag) - "Show message at cursor. -If optional argument MESSAGE is non-nil, display that message instead. -Force a two-window display with the folder window on top (size given by the -variable `mh-summary-height') and the show buffer below it. -If the message is already visible, display the start of the message. + "Display message\\. + +If the message under the cursor is already displayed, this command scrolls to +the beginning of the message. MH-E normally hides a lot of the superfluous +header fields that mailers add to a message, but if you wish to see all of +them, use the command \\[mh-header-display]. -If REDISPLAY-FLAG is non-nil, the default when called interactively, the -message is redisplayed even if the show buffer was already displaying the -correct message. +From a program, optional argument MESSAGE can be used to display an +alternative message. The optional argument REDISPLAY-FLAG forces the redisplay +of the message even if the show buffer was already displaying the correct +message. -Display of the message is controlled by setting the variables -`mh-clean-message-header-flag' and `mhl-formfile'. The default behavior is -to scroll uninteresting headers off the top of the window. -Type \"\\[mh-header-display]\" to see the message with all its headers." +See the \"mh-show\" customization group for a litany of options that control +what displayed messages look like." (interactive (list nil t)) (when (or redisplay-flag (and mh-showing-with-headers - (or mhl-formfile mh-clean-message-header-flag))) + (or mh-mhl-format-file mh-clean-message-header-flag))) (mh-invalidate-show-buffer)) (mh-show-msg message)) @@ -1639,13 +1635,14 @@ (run-hooks 'mh-show-hook))) (defun mh-modify (&optional message) - "Edit message at cursor. -If optional argument MESSAGE is non-nil, edit that message instead. -Force a two-window display with the folder window on top (size given by the -value of the variable `mh-summary-height') and the message editing buffer below -it. + "Edit message. -The message is displayed in raw form." +There are times when you need to edit a message. For example, you may need to +fix a broken Content-Type header field. You can do this with this command. It +displays the raw message in an editable buffer. When you are done editing, +save and kill the buffer as you would any other. + +From a program, edit MESSAGE instead if it is non-nil." (interactive) (let* ((message (or message (mh-get-msg-num t))) (msg-filename (mh-msg-filename message)) @@ -1700,7 +1697,7 @@ (unless (mh-buffer-data) (setf (mh-buffer-data) (mh-make-buffer-data))) ;; Bind variables in folder buffer in case they are local - (let ((formfile mhl-formfile) + (let ((formfile mh-mhl-format-file) (clean-message-header mh-clean-message-header-flag) (invisible-headers mh-invisible-header-fields-compiled) (visible-headers nil) @@ -1849,11 +1846,15 @@ (mh-thread-update-scan-line-map msg notation offset))))))) (defun mh-goto-msg (number &optional no-error-if-no-message dont-show) - "Position the cursor at message NUMBER. -Optional non-nil second argument NO-ERROR-IF-NO-MESSAGE means return nil -instead of signaling an error if message does not exist; in this case, the -cursor is positioned near where the message would have been. -Non-nil third argument DONT-SHOW means not to show the message." + "Go to a message\\. + +You can enter the message NUMBER either before or after typing +\\[mh-goto-msg]. In the latter case, Emacs prompts you. + +In a program, optional non-nil second argument NO-ERROR-IF-NO-MESSAGE means +return nil instead of signaling an error if message does not exist\; in this +case, the cursor is positioned near where the message would have been. Non-nil +third argument DONT-SHOW means not to show the message." (interactive "NGo to message: ") (setq number (prefix-numeric-value number)) (let ((point (point)) diff -r 8e25aa911e3e -r 37d0562504bf lisp/play/yow.el --- a/lisp/play/yow.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/play/yow.el Sat Dec 10 21:18:28 2005 +0000 @@ -102,7 +102,8 @@ (while l (princ (car l)) (setq l (cdr l)) - (and l (princ "\n\n")))))))) + (and l (princ "\n\n"))) + (print-help-return-message)))))) matches)) diff -r 8e25aa911e3e -r 37d0562504bf lisp/progmodes/cc-align.el --- a/lisp/progmodes/cc-align.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/progmodes/cc-align.el Sat Dec 10 21:18:28 2005 +0000 @@ -45,19 +45,10 @@ (cc-require 'cc-engine) -;; Standard indentation line-ups - -;; Calling convention: +;; Standard line-up functions ;; -;; The single argument is a cons cell containing the syntactic symbol -;; in the car, and the relpos (a.k.a. anchor position) in the cdr. -;; The cdr may be nil for syntactic symbols which doesn't have an -;; associated relpos. -;; -;; Some syntactic symbols provide more information, usually more -;; interesting positions. The complete list for the syntactic element -;; (beginning with the symbol itself) is available in -;; `c-syntactic-element'. +;; See the section "Custom Indentation Functions" in the manual for +;; details on the calling convention. (defun c-lineup-topmost-intro-cont (langelem) "Line up declaration continuation lines zero or one indentation step. @@ -91,17 +82,67 @@ Works with: topmost-intro-cont." (save-excursion (beginning-of-line) - (c-backward-syntactic-ws (cdr langelem)) - (if (memq (char-before) '(?} ?,)) + (c-backward-syntactic-ws (c-langelem-pos langelem)) + (if (and (memq (char-before) '(?} ?,)) + (not (and c-overloadable-operators-regexp + (c-after-special-operator-id)))) c-basic-offset))) +(defun c-block-in-arglist-dwim (arglist-start) + ;; This function implements the DWIM to avoid far indentation of + ;; brace block constructs in arguments in `c-lineup-arglist' etc. + ;; Return non-nil if a brace block construct is detected within the + ;; arglist starting at ARGLIST-START. + + (or + ;; Check if the syntactic context contains any of the symbols for + ;; in-expression constructs. This can both save the work that we + ;; have to do below, and it also detect the brace list constructs + ;; that `c-looking-at-inexpr-block' currently misses (they are + ;; recognized by `c-inside-bracelist-p' instead). + (assq 'inexpr-class c-syntactic-context) + (assq 'inexpr-statement c-syntactic-context) + (assq 'inlambda c-syntactic-context) + + (save-restriction + ;; Search for open braces from the arglist start to the end of the + ;; line. + (narrow-to-region arglist-start (c-point 'eol arglist-start)) + + (goto-char arglist-start) + (while (and (c-syntactic-re-search-forward "{" nil t) + (progn + (backward-char) + (or + ;; Ignore starts of special brace lists. + (and c-special-brace-lists + (save-restriction + (widen) + (c-looking-at-special-brace-list))) + ;; Ignore complete blocks. + (c-safe (c-forward-sexp) t)))) + (forward-char)) + + (looking-at "{")) + + (let (containing-sexp) + (goto-char arglist-start) + ;; `c-syntactic-eol' always matches somewhere on the line. + (re-search-forward c-syntactic-eol) + (goto-char (match-beginning 0)) + (c-forward-syntactic-ws) + (setq containing-sexp (c-most-enclosing-brace (c-parse-state))) + (c-looking-at-inexpr-block + (c-safe-position (or containing-sexp (point)) c-state-cache) + containing-sexp)))) + (defun c-lineup-arglist (langelem) "Line up the current argument line under the first argument. -As a special case, if an argument on the same line as the open -parenthesis starts with a brace block opener, the indentation is -`c-basic-offset' only. This is intended as a \"DWIM\" measure in -cases like macros that contains statement blocks, e.g: +As a special case, if the indented line is inside a brace block +construct, the indentation is `c-basic-offset' only. This is intended +as a \"DWIM\" measure in cases like macros that contains statement +blocks, e.g: A_VERY_LONG_MACRO_NAME ({ some (code, with + long, lines * in[it]); @@ -115,38 +156,25 @@ Works with: arglist-cont-nonempty, arglist-close." (save-excursion - (goto-char (1+ (elt c-syntactic-element 2))) - - ;; Don't stop in the middle of a special brace list opener - ;; like "({". - (when c-special-brace-lists - (let ((special-list (c-looking-at-special-brace-list))) - (when (and special-list (< (car (car special-list)) (point))) - (goto-char (+ (car (car special-list)) 2))))) - - (let ((savepos (point)) - (eol (c-point 'eol))) + (let ((indent-pos (point))) - ;; Find out if an argument on the same line starts with an - ;; unclosed open brace paren. Note similar code in - ;; `c-lineup-close-paren' and - ;; `c-lineup-arglist-close-under-paren'. - (if (and (c-syntactic-re-search-forward "{" eol t t) - (looking-at c-syntactic-eol) - (progn (backward-char) - (not (c-looking-at-special-brace-list))) - (progn (c-backward-syntactic-ws) - (or (= (point) savepos) - (eq (char-before) ?,)))) - c-basic-offset + (if (c-block-in-arglist-dwim (c-langelem-2nd-pos c-syntactic-element)) + c-basic-offset ; DWIM case. ;; Normal case. Indent to the token after the arglist open paren. - (goto-char savepos) - (c-forward-syntactic-ws) - (when (< (point) eol) - (goto-char savepos) - (skip-chars-forward " \t")) - (vector (current-column)))))) + (goto-char (c-langelem-2nd-pos c-syntactic-element)) + (if (and c-special-brace-lists + (c-looking-at-special-brace-list)) + ;; Skip a special brace list opener like "({". + (progn (c-forward-token-2) + (forward-char)) + (forward-char)) + (let ((arglist-content-start (point))) + (c-forward-syntactic-ws) + (when (< (point) indent-pos) + (goto-char arglist-content-start) + (skip-chars-forward " \t")) + (vector (current-column))))))) ;; Contributed by Kevin Ryde . (defun c-lineup-argcont (elem) @@ -172,7 +200,7 @@ ;; isn't, go back to the last position in it. We do this by ;; stepping back over open parens until we get to the open paren ;; of our argument list. - (let ((open-paren (elt c-syntactic-element 2)) + (let ((open-paren (c-langelem-2nd-pos c-syntactic-element)) (paren-state (c-parse-state))) (while (not (eq (car paren-state) open-paren)) (unless (consp (car paren-state)) ;; ignore matched braces @@ -233,51 +261,36 @@ arglist-cont-nonempty to line up all lines inside a parenthesis under the open paren. -As a special case, if a brace block is opened at the same line as the -open parenthesis of the argument list, the indentation is +As a special case, if a brace block construct starts at the same line +as the open parenthesis of the argument list, the indentation is `c-basic-offset' only. See `c-lineup-arglist' for further discussion of this \"DWIM\" measure. Works with: Almost all symbols, but are typically most useful on arglist-close, brace-list-close, arglist-cont and arglist-cont-nonempty." (save-excursion - (let (special-list paren-start savepos) - (if (memq (car langelem) '(arglist-cont-nonempty arglist-close)) - (goto-char (elt c-syntactic-element 2)) - (beginning-of-line) - (c-go-up-list-backward)) - - (if (and c-special-brace-lists - (setq special-list (c-looking-at-special-brace-list))) - ;; Don't stop in the middle of a special brace list opener - ;; like "({". - (progn - (setq paren-start (car (car special-list))) - (goto-char (+ paren-start 2))) - (setq paren-start (point)) - (forward-char 1)) + (if (memq (c-langelem-sym langelem) + '(arglist-cont-nonempty arglist-close)) + (goto-char (c-langelem-2nd-pos c-syntactic-element)) + (beginning-of-line) + (c-go-up-list-backward)) - (setq savepos (point)) - ;; Find out if an argument on the same line starts with an - ;; unclosed open brace paren. Note similar code in - ;; `c-lineup-arglist' and `c-lineup-close-paren'. - (if (and (c-syntactic-re-search-forward "{" (c-point 'eol) t t) - (looking-at c-syntactic-eol) - (progn (backward-char) - (not (c-looking-at-special-brace-list))) - (progn (c-backward-syntactic-ws) - (or (= (point) savepos) - (eq (char-before) ?,)))) - c-basic-offset + (if (save-excursion (c-block-in-arglist-dwim (point))) + c-basic-offset ; DWIM case. - ;; Normal case. Indent to the arglist open paren. - (goto-char paren-start) + ;; Normal case. Indent to the arglist open paren. + (let (special-list) + (if (and c-special-brace-lists + (setq special-list (c-looking-at-special-brace-list))) + ;; Cope if we're in the middle of a special brace list + ;; opener like "({". + (goto-char (car (car special-list)))) (vector (current-column)))))) (defun c-lineup-arglist-operators (langelem) "Line up lines starting with an infix operator under the open paren. Return nil on lines that don't start with an operator, to leave those -cases to other lineup functions. Example: +cases to other line-up functions. Example: if ( x < 10 || at_limit (x, <- c-lineup-arglist-operators @@ -285,7 +298,7 @@ ) Since this function doesn't do anything for lines without an infix -operator you typically want to use it together with some other lineup +operator you typically want to use it together with some other line-up settings, e.g. as follows \(the arglist-close setting is just a suggestion to get a consistent style): @@ -310,52 +323,48 @@ char ** int, char ** ) <-> ) <- c-lineup-close-paren -As a special case, if a brace block is opened at the same line as the -open parenthesis of the argument list, the indentation is +As a special case, if a brace block construct starts at the same line +as the open parenthesis of the argument list, the indentation is `c-basic-offset' instead of the open paren column. See `c-lineup-arglist' for further discussion of this \"DWIM\" measure. Works with: All *-close symbols." (save-excursion - (beginning-of-line) - (c-go-up-list-backward) - - (let ((spec (c-looking-at-special-brace-list)) savepos argstart) - (if spec (goto-char (car (car spec)))) - (setq savepos (point)) - (forward-char 1) - (when spec - (c-forward-syntactic-ws) - (forward-char 1)) - - (if (looking-at c-syntactic-eol) - ;; The arglist is "empty". - 0 + (if (memq (c-langelem-sym langelem) + '(arglist-cont-nonempty arglist-close)) + (goto-char (c-langelem-2nd-pos c-syntactic-element)) + (beginning-of-line) + (c-go-up-list-backward)) - ;; Find out if an argument on the same line starts with an - ;; unclosed open brace paren. Note similar code in - ;; `c-lineup-arglist' and - ;; `c-lineup-arglist-close-under-paren'. - (setq argstart (point)) - (if (and (c-syntactic-re-search-forward "{" (c-point 'eol) t t) - (looking-at c-syntactic-eol) - (progn (backward-char) - (not (c-looking-at-special-brace-list))) - (progn (c-backward-syntactic-ws) - (or (= (point) argstart) - (eq (char-before) ?,)))) - c-basic-offset + (let (special-list arglist-start) + (if (and c-special-brace-lists + (setq special-list (c-looking-at-special-brace-list))) + ;; Cope if we're in the middle of a special brace list + ;; opener like "({". + (progn + (goto-char (setq arglist-start (car (car special-list)))) + (c-forward-token-2) + (forward-char)) + (setq arglist-start (point)) + (forward-char)) - ;; Normal case. Indent to the arglist open paren. - (goto-char savepos) - (vector (current-column))))))) + (cond ((looking-at c-syntactic-eol) + 0) ; The arglist is "empty". + + ((c-block-in-arglist-dwim (point)) + c-basic-offset) ; DWIM case. + + (t + ;; Normal case. Indent to the arglist open paren. + (goto-char arglist-start) + (vector (current-column))))))) (defun c-lineup-streamop (langelem) "Line up C++ stream operators under each other. Works with: stream-op." (save-excursion - (goto-char (cdr langelem)) + (goto-char (c-langelem-pos langelem)) (re-search-forward "<<\\|>>" (c-point 'eol) 'move) (goto-char (match-beginning 0)) (vector (current-column)))) @@ -382,7 +391,8 @@ (let* ((eol (c-point 'eol)) (here (point)) (char-after-ip (char-after))) - (if (cdr langelem) (goto-char (cdr langelem))) + (if (c-langelem-pos langelem) + (goto-char (c-langelem-pos langelem))) ;; This kludge is necessary to support both inher-cont and ;; member-init-cont, since they have different anchor positions. @@ -415,7 +425,7 @@ Works with: inher-cont." (save-excursion - (goto-char (cdr langelem)) + (goto-char (c-langelem-pos langelem)) (forward-word 1) (if (looking-at "[ \t]*$") c-basic-offset @@ -439,7 +449,7 @@ (save-excursion (let* ((lim (1- (c-point 'bol))) (throws (catch 'done - (goto-char (cdr langelem)) + (goto-char (c-langelem-pos langelem)) (while (zerop (c-forward-token-2 1 t lim)) (if (looking-at "throws\\>[^_]") (throw 'done t)))))) @@ -537,13 +547,13 @@ ;; matches comment-start-skip, and choose whichever is ;; longest. (max (save-excursion - (goto-char (1+ (cdr langelem))) + (goto-char (1+ (c-langelem-pos langelem))) (if (and (match-string 0) (looking-at (regexp-quote (match-string 0)))) (- (match-end 0) (match-beginning 0)) 0)) (save-excursion - (goto-char (cdr langelem)) + (goto-char (c-langelem-pos langelem)) (looking-at comment-start-skip) (- (or (match-end 1) (save-excursion @@ -557,14 +567,20 @@ ;; a nonempty comment prefix. Treat it as free form text ;; and don't change the indentation. (vector (current-column)) - (forward-line -1) - (back-to-indentation) - (if (>= (cdr langelem) (point)) - ;; On the second line in the comment. + ;; Go back to the previous non-blank line, if any. + (while + (progn + (forward-line -1) + (back-to-indentation) + (and (> (point) (c-langelem-pos langelem)) + (looking-at "[ \t]*$")))) + ;; Is the starting line the first continuation line with content? + (if (>= (c-langelem-pos langelem) (point)) (if (zerop prefixlen) ;; No nonempty comment prefix. Align after comment ;; starter. (progn + (looking-at comment-start-skip) (goto-char (match-end 0)) ;; The following should not be necessary, since ;; comment-start-skip should match everything (i.e. @@ -580,27 +596,27 @@ ;; Javadoc style comments. (if (> starterlen prefixlen) (progn - (goto-char (cdr langelem)) + (goto-char (c-langelem-pos langelem)) (vector (1+ (current-column)))) - (goto-char (+ (cdr langelem) starterlen 1)) + (goto-char (+ (c-langelem-pos langelem) starterlen 1)) (vector (- (current-column) prefixlen)))) - ;; Not on the second line in the comment. If the previous - ;; line has a nonempty comment prefix, align with it. - ;; Otherwise, align with the previous nonempty line, but - ;; align the comment ender with the starter. + ;; We didn't start on the first non-blank continuation line. If the + ;; previous line has a nonempty comment prefix, align with it. + ;; Otherwise, align with the previous nonempty line, but align the + ;; comment ender with the starter. (when (or (not (looking-at c-current-comment-prefix)) (eq (match-beginning 0) (match-end 0))) (goto-char here) (back-to-indentation) (if (looking-at (concat "\\(" c-current-comment-prefix "\\)\\*/")) - (goto-char (cdr langelem)) + (goto-char (c-langelem-pos langelem)) (while (and (zerop (forward-line -1)) (looking-at "^[ \t]*$"))) (back-to-indentation) - (if (< (point) (cdr langelem)) + (if (< (point) (c-langelem-pos langelem)) ;; Align with the comment starter rather than ;; with the code before it. - (goto-char (cdr langelem))))) + (goto-char (c-langelem-pos langelem))))) (vector (current-column))))))) (defun c-lineup-comment (langelem) @@ -665,38 +681,39 @@ returned. This makes the function usable in list expressions. Works with: The `statement' syntactic symbol." - (if (eq (char-after (cdr langelem)) ?{) + (if (eq (char-after (c-langelem-pos langelem)) ?{) (save-excursion - (if (cdr langelem) (goto-char (cdr langelem))) + (if (c-langelem-pos langelem) + (goto-char (c-langelem-pos langelem))) (forward-char 1) (skip-chars-forward " \t") (unless (eolp) (vector (current-column)))))) -(defun c-lineup-math (langelem) - "Line up the current line after the equal sign on the first line in -the statement. If there isn't any, indent with `c-basic-offset'. If -the current line contains an equal sign too, try to align it with the -first one. +(defun c-lineup-assignments (langelem) + "Line up the current line after the assignment operator on the first +line in the statement. If there isn't any, return nil to allow +stacking with other line-up functions. If the current line contains +an assignment operator too, try to align it with the first one. Works with: topmost-intro-cont, statement-cont, arglist-cont, arglist-cont-nonempty." (let (startpos endpos equalp) - (if (eq (car langelem) 'arglist-cont-nonempty) + (if (eq (c-langelem-sym langelem) 'arglist-cont-nonempty) ;; If it's an arglist-cont-nonempty then we're only interested ;; in equal signs outside it. We don't search for a "=" on ;; the current line since that'd have a different nesting ;; compared to the one we should align with. (save-excursion (save-restriction - (setq endpos (nth 2 c-syntactic-element)) - (narrow-to-region (cdr langelem) endpos) + (setq endpos (c-langelem-2nd-pos c-syntactic-element)) + (narrow-to-region (c-langelem-pos langelem) endpos) (if (setq startpos (c-up-list-backward endpos)) (setq startpos (1+ startpos)) - (setq startpos (cdr langelem))))) + (setq startpos (c-langelem-pos langelem))))) - (setq startpos (cdr langelem) + (setq startpos (c-langelem-pos langelem) endpos (point)) ;; Find a syntactically relevant and unnested "=" token on the @@ -727,7 +744,7 @@ (eolp))) ;; There's no equal sign on the line, or there is one but ;; nothing follows it. - c-basic-offset + nil ;; calculate indentation column after equals and ws, unless ;; our line contains an equals sign @@ -739,6 +756,17 @@ (vector (- (current-column) equalp))) ))) +(defun c-lineup-math (langelem) + "Like `c-lineup-assignments' but indent with `c-basic-offset' if no +assignment operator was found on the first line. I.e. this function +is the same as specifying a list (c-lineup-assignments +). It's +provided for compatibility with old configurations. + +Works with: topmost-intro-cont, statement-cont, arglist-cont, +arglist-cont-nonempty." + (or (c-lineup-assignments langelem) + c-basic-offset)) + (defun c-lineup-cascaded-calls (langelem) "Line up \"cascaded calls\" under each other. If the line begins with \"->\" or \".\" and the preceding line ends @@ -755,8 +783,8 @@ Works with: topmost-intro-cont, statement-cont, arglist-cont, arglist-cont-nonempty." - (if (and (eq (car langelem) 'arglist-cont-nonempty) - (not (eq (nth 2 c-syntactic-element) + (if (and (eq (c-langelem-sym langelem) 'arglist-cont-nonempty) + (not (eq (c-langelem-2nd-pos c-syntactic-element) (c-most-enclosing-brace (c-parse-state))))) ;; The innermost open paren is not our one, so don't do ;; anything. This can occur for arglist-cont-nonempty with @@ -767,7 +795,7 @@ (back-to-indentation) (let ((operator (and (looking-at "->\\|\\.") (regexp-quote (match-string 0)))) - (stmt-start (cdr langelem)) col) + (stmt-start (c-langelem-pos langelem)) col) (when (and operator (looking-at operator) @@ -794,7 +822,7 @@ \"string.\"; <- c-lineup-string-cont Nil is returned in other situations, to allow stacking with other -lineup functions. +line-up functions. Works with: topmost-intro-cont, statement-cont, arglist-cont, arglist-cont-nonempty." @@ -829,18 +857,18 @@ Go to the position right after the message receiver, and if you are at the end of the line, indent the current line c-basic-offset columns from the opening bracket; otherwise you are looking at the first -character of the first method call argument, so lineup the current +character of the first method call argument, so line up the current line with it. Works with: objc-method-call-cont." (save-excursion (let* ((extra (save-excursion (back-to-indentation) - (c-backward-syntactic-ws (cdr langelem)) + (c-backward-syntactic-ws (c-langelem-pos langelem)) (if (eq (char-before) ?:) (- c-basic-offset) 0))) - (open-bracket-pos (cdr langelem)) + (open-bracket-pos (c-langelem-pos langelem)) (open-bracket-col (progn (goto-char open-bracket-pos) (current-column))) @@ -864,7 +892,7 @@ (let* ((here (c-point 'boi)) (curcol (progn (goto-char here) (current-column))) (eol (c-point 'eol)) - (relpos (cdr langelem)) + (relpos (c-langelem-pos langelem)) (first-col-column (progn (goto-char relpos) (skip-chars-forward "^:" eol) @@ -888,7 +916,7 @@ (let* ((here (c-point 'boi)) (curcol (progn (goto-char here) (current-column))) (eol (c-point 'eol)) - (relpos (cdr langelem)) + (relpos (c-langelem-pos langelem)) (prev-col-column (progn (skip-chars-backward "^:" relpos) (and (eq (char-before) ?:) @@ -927,13 +955,10 @@ containing-sexp)))))) (when res (goto-char (cdr res)) - (- (current-column) - (progn - (back-to-indentation) - (current-column))))))) + (vector (current-column)))))) (defun c-lineup-whitesmith-in-block (langelem) - "Line up lines inside a block in whitesmith style. + "Line up lines inside a block in Whitesmith style. It's done in a way that works both when the opening brace hangs and when it doesn't. E.g: @@ -946,21 +971,54 @@ In the first case the indentation is kept unchanged, in the second `c-basic-offset' is added. -Works with: defun-close, defun-block-intro, block-close, -brace-list-close, brace-list-intro, statement-block-intro and all in* +Works with: defun-close, defun-block-intro, inline-close, block-close, +brace-list-close, brace-list-intro, statement-block-intro, +arglist-intro, arglist-cont-nonempty, arglist-close, and all in* symbols, e.g. inclass and inextern-lang." (save-excursion - (+ (progn - (back-to-indentation) - (if (eq (char-syntax (char-after)) ?\() - c-basic-offset - 0)) - (progn - (goto-char (cdr langelem)) - (back-to-indentation) - (if (eq (char-syntax (char-after)) ?\() - 0 - c-basic-offset))))) + (if (and (c-go-up-list-backward) + (= (point) (c-point 'boi))) + nil + c-basic-offset))) + +(defun c-lineup-after-whitesmith-blocks (langelem) + "Compensate for Whitesmith style indentation of blocks. +Due to the way CC Mode calculates anchor positions for normal lines +inside blocks, this function is necessary for those lines to get +correct Whitesmith style indentation. Consider the following +examples: + + int foo() + { +int foo() { + { a; + a; } + x; <-> x; <- c-lineup-after-whitesmith-blocks + +The fact that the line with \"x\" is preceded by a Whitesmith style +indented block in one case and not the other should not affect its +indentation. But since CC Mode in cases like this uses the +indentation of the preceding statement as anchor position, the \"x\" +would in the rightmost case be indented too much if the offset for +`statement' was set simply to zero. + +This lineup function corrects for this situation by detecting if the +anchor position is at an open paren character. In that case, it +instead indents relative to the surrounding block just like +`c-lineup-whitesmith-in-block'. + +Works with: brace-list-entry, brace-entry-open, statement, +arglist-cont." + (save-excursion + (goto-char (c-langelem-pos langelem)) + (when (looking-at "\\s\(") + (if (c-go-up-list-backward) + (let ((pos (point))) + (back-to-indentation) + (if (= pos (point)) + (vector (current-column)) + (vector (+ (current-column) c-basic-offset)))) + (vector 0))))) (defun c-lineup-cpp-define (langelem) "Line up macro continuation lines according to the indentation of @@ -1058,9 +1116,10 @@ The \"x\" line is aligned to the text after the \":\" on the \"w\" line, and similarly \"z\" under \"y\". -This is done only in an \"asm\" or \"__asm__\" block, and only to those -lines mentioned. Anywhere else nil is returned. The usual arrangement is -to have this routine as an extra feature at the start of arglist lineups, e.g. +This is done only in an \"asm\" or \"__asm__\" block, and only to +those lines mentioned. Anywhere else nil is returned. The usual +arrangement is to have this routine as an extra feature at the start +of arglist line-ups, e.g. (c-lineup-gcc-asm-reg c-lineup-arglist) @@ -1076,7 +1135,7 @@ ;; This can occur for arglist-cont-nonempty with nested arglist ;; starts on the same line. (or (not (eq (car elem) 'arglist-cont-nonempty)) - (eq (elt c-syntactic-element 2) + (eq (c-langelem-2nd-pos c-syntactic-element) (c-most-enclosing-brace (c-parse-state)))) ;; Find the ":" to align to. Look for this first so as to quickly @@ -1117,13 +1176,24 @@ (let (langelem) (if (and (eq syntax 'block-close) (setq langelem (assq 'block-close c-syntactic-context)) - (progn (goto-char (elt langelem 1)) + (progn (goto-char (c-langelem-pos langelem)) (if (eq (char-after) ?{) (c-safe (c-forward-sexp -1))) (looking-at "\\[^_]"))) '(before) '(before after))))) +(defun c-snug-1line-defun-close (syntax pos) + "Determine the brace hanginess for an AWK defun-close. +If the action/function being closed is a one-liner, keep it so. Otherwise put +the closing brace on its own line." + (save-excursion + (goto-char pos) + (if (> (c-point 'bol) + (progn (up-list -1) (point))) + '(before after) + '(after)))) + (defun c-gnu-impose-minimum () "Imposes a minimum indentation for lines inside code blocks. The variable `c-label-minimum-indentation' specifies the minimum diff -r 8e25aa911e3e -r 37d0562504bf lisp/progmodes/cc-awk.el --- a/lisp/progmodes/cc-awk.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/progmodes/cc-awk.el Sat Dec 10 21:18:28 2005 +0000 @@ -1,7 +1,7 @@ ;;; cc-awk.el --- AWK specific code within cc-mode. -;; Copyright (C) 1988, 94, 96, 2000, 2001, 2002, 2003, 2004, 2005 -;; Free Software Foundation, Inc. +;; Copyright (C) 1988,94,96,2000, 2001, 2002, 2003, 2004, 2005 Free +;; Software Foundation, Inc. ;; Author: Alan Mackenzie (originally based on awk-mode.el) ;; Maintainer: FSF @@ -20,7 +20,7 @@ ;; 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 +;; along with this program; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. @@ -28,13 +28,14 @@ ;; This file contains (most of) the adaptations to cc-mode required for the ;; integration of AWK Mode. -;; It is organised thusly: +;; It is organised thusly, the sections being separated by page breaks: ;; 1. The AWK Mode syntax table. -;; 2. Indentation calculation stuff ("c-awk-NL-prop text-property"). -;; 3. Syntax-table property/font-locking stuff, but not including the +;; 2. Regular expressions for analysing AWK code. +;; 3. Indentation calculation stuff ("c-awk-NL-prop text-property"). +;; 4. Syntax-table property/font-locking stuff, but not including the ;; font-lock-keywords setting. -;; 4. The AWK Mode before/after-change-functions. -;; 5. AWK Mode specific versions of commands like beginning-of-defun. +;; 5. The AWK Mode before/after-change-functions. +;; 6. AWK Mode specific versions of commands like beginning-of-defun. ;; The AWK Mode keymap, abbreviation table, and the mode function itself are ;; in cc-mode.el. @@ -70,7 +71,7 @@ ;; / can delimit regexes or be a division operator. By default we assume ;; that it is a division sign, and fix the regexp operator cases with ;; `font-lock-syntactic-keywords'. - (modify-syntax-entry ?/ "." st) ; ACM 2002/4/27. + (modify-syntax-entry ?/ "." st) ; ACM 2002/4/27. (modify-syntax-entry ?* "." st) (modify-syntax-entry ?+ "." st) (modify-syntax-entry ?- "." st) @@ -85,378 +86,8 @@ st) "Syntax table in use in AWK Mode buffers.") -;; ACM, 2002/5/29: -;; -;; The next section of code is about determining whether or not an AWK -;; statement is complete or not. We use this to indent the following line. -;; The determination is pretty straightforward in C, where a statement ends -;; with either a ; or a }. Only "while" really gives any trouble there, since -;; it might be the end of a do-while. In AWK, on the other hand, semicolons -;; are rarely used, and EOLs _usually_ act as "virtual semicolons". In -;; addition, we have the complexity of escaped EOLs. The core of this -;; analysis is in the middle of the function -;; c-awk-calculate-NL-prop-prev-line, about 130 lines lower down. -;; -;; To avoid continually repeating this expensive analysis, we "cache" its -;; result in a text-property, c-awk-NL-prop, whose value for a line is set on -;; the EOL (if any) which terminates that line. Should the property be -;; required for the very last line (which has no EOL), it is calculated as -;; required but not cached. The c-awk-NL-prop property should be thought of -;; as only really valid immediately after a buffer change, not a permanently -;; set property. (By contrast, the syntax-table text properties (set by an -;; after-change function) must be constantly updated for the mode to work -;; properly). -;; -;; The valid values for c-awk-NL-prop are: -;; -;; nil The property is not currently set for this line. -;; '#' There is NO statement on this line (at most a comment), and no open -;; statement from a previous line which could have been completed on this -;; line. -;; '{' There is an unfinished statement on this (or a previous) line which -;; doesn't require \s to continue onto another line, e.g. the line ends -;; with {, or the && operator, or "if (condition)". Note that even if the -;; newline is redundantly escaped, it remains a '{' line. -;; '\' There is an escaped newline at the end of this line and this '\' is -;; essential to the syntax of the program. (i.e. if it had been a -;; frivolous \, it would have been ignored and the line been given one of -;; the other property values.) -;; ';' A statement is completed as the last thing (aside from ws) on the line - -;; i.e. there is (at least part of) a statement on this line, and the last -;; statement on the line is complete, OR (2002/10/25) the line is -;; content-free but terminates a statement from the preceding (continued) -;; line (which has property \). -;; -;; This set of values has been chosen so that the property's value on a line -;; is completely determined by the contents of the line and the property on -;; the previous line, EXCEPT for where a "while" might be the closing -;; statement of a do-while. - -(defun c-awk-after-if-for-while-condition-p (&optional do-lim) - ;; Are we just after the ) in "if/for/while ()"? - ;; - ;; Note that the end of the ) in a do .... while () doesn't - ;; count, since the purpose of this routine is essentially to decide - ;; whether to indent the next line. - ;; - ;; DO-LIM sets a limit on how far back we search for the "do" of a possible - ;; do-while. - (and - (eq (char-before) ?\)) - (save-excursion - (let ((par-pos (c-safe (scan-lists (point) -1 0)))) - (when par-pos - (goto-char par-pos) ; back over "(...)" - (c-backward-token-1) ; BOB isn't a problem. - (or (looking-at "\\(if\\|for\\)\\>\\([^_]\\|$\\)") - (and (looking-at "while\\>\\([^_]\\|$\\)") ; Ensure this isn't a do-while. - (not (eq (c-beginning-of-statement-1 do-lim) - 'beginning))))))))) - -(defun c-awk-after-function-decl-param-list () - ;; Are we just after the ) in "function foo (bar)" ? - (and (eq (char-before) ?\)) - (save-excursion - (let ((par-pos (c-safe (scan-lists (point) -1 0)))) - (when par-pos - (goto-char par-pos) ; back over "(...)" - (c-backward-token-1) ; BOB isn't a problem - (and (looking-at "[_a-zA-Z][_a-zA-Z0-9]*\\>") - (progn (c-backward-token-1) - (looking-at "func\\(tion\\)?\\>")))))))) - -;; 2002/11/8: FIXME! Check c-backward-token-1/2 for success (0 return code). -(defun c-awk-after-continue-token () -;; Are we just after a token which can be continued onto the next line without -;; a backslash? - (save-excursion - (c-backward-token-1) ; FIXME 2002/10/27. What if this fails? - (if (and (looking-at "[&|]") (not (bobp))) - (backward-char)) ; c-backward-token-1 doesn't do this :-( - (looking-at "[,{?:]\\|&&\\|||\\|do\\>\\|else\\>"))) - -(defun c-awk-after-rbrace-or-statement-semicolon () - ;; Are we just after a } or a ; which closes a statement? - ;; Be careful about ;s in for loop control bits. They don't count! - (or (eq (char-before) ?\}) - (and - (eq (char-before) ?\;) - (save-excursion - (let ((par-pos (c-safe (scan-lists (point) -1 1)))) - (when par-pos - (goto-char par-pos) ; go back to containing ( - (not (and (looking-at "(") - (c-backward-token-1) ; BOB isn't a problem - (looking-at "for\\>"))))))))) - -(defun c-awk-back-to-contentful-text-or-NL-prop () - ;; Move back to just after the first found of either (i) an EOL which has - ;; the c-awk-NL-prop text-property set; or (ii) non-ws text; or (iii) BOB. - ;; We return either the value of c-awk-NL-prop (in case (i)) or nil. - ;; Calling function can best distinguish cases (ii) and (iii) with (bolp). - ;; - ;; Note that an escaped eol counts as whitespace here. - ;; - ;; Kludge: If c-backward-syntactic-ws gets stuck at a BOL, it is likely - ;; that the previous line contains an unterminated string (without \). In - ;; this case, assume that the previous line's c-awk-NL-prop is a ;. - ;; - ;; POINT MUST BE AT THE START OF A LINE when calling this function. This - ;; is to ensure that the various backward-comment functions will work - ;; properly. - (let ((nl-prop nil) - bol-pos bsws-pos) ; starting pos for a backward-syntactic-ws call. - (while ;; We are at a BOL here. Go back one line each iteration. - (and - (not (bobp)) - (not (setq nl-prop (c-get-char-property (1- (point)) 'c-awk-NL-prop))) - (progn (setq bol-pos (c-point 'bopl)) - (setq bsws-pos (point)) - ;; N.B. the following function will not go back past an EOL if - ;; there is an open string (without \) on the previous line. - (c-backward-syntactic-ws bol-pos) - (or (/= (point) bsws-pos) - (progn (setq nl-prop ?\;) - nil))) - ;; If we had a backslash at EOL, c-backward-syntactic-ws will - ;; have gone backwards over it. Check the backslash was "real". - (progn - (if (looking-at "[ \t]*\\\\+$") - (if (progn - (end-of-line) - (search-backward-regexp - "\\(^\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\$" ; ODD number of \s at EOL :-) - bol-pos t)) - (progn (end-of-line) ; escaped EOL. - (backward-char) - (c-backward-syntactic-ws bol-pos)) - (end-of-line))) ; The \ at eol is a fake. - (bolp)))) - nl-prop)) - -(defun c-awk-calculate-NL-prop-prev-line (&optional do-lim) - ;; Calculate and set the value of the c-awk-NL-prop on the immediately - ;; preceding EOL. This may also involve doing the same for several - ;; preceding EOLs. - ;; - ;; NOTE that if the property was already set, we return it without - ;; recalculation. (This is by accident rather than design.) - ;; - ;; Return the property which got set (or was already set) on the previous - ;; line. Return nil if we hit BOB. - ;; - ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. - (save-excursion - (save-match-data - (beginning-of-line) - (let* ((pos (point)) - (nl-prop (c-awk-back-to-contentful-text-or-NL-prop))) - ;; We are either (1) at a BOL (with nl-prop containing the previous - ;; line's c-awk-NL-prop) or (2) after contentful text on a line. At - ;; the BOB counts as case (1), so we test next for bolp rather than - ;; non-nil nl-prop. - (when (not (bolp)) - (setq nl-prop - (cond - ;; Incomplete statement which doesn't require escaped EOL? - ((or (c-awk-after-if-for-while-condition-p do-lim) - (c-awk-after-function-decl-param-list) - (c-awk-after-continue-token)) - ?\{) - ;; Escaped EOL (where there's also something to continue)? - ((and (looking-at "[ \t]*\\\\$") - (not (c-awk-after-rbrace-or-statement-semicolon))) - ?\\) - (t ?\;))) ; A statement was completed on this line - (end-of-line) - (c-put-char-property (point) 'c-awk-NL-prop nl-prop) - (forward-line)) - - ;; We are now at a (possibly empty) sequence of content-free lines. - ;; Set c-awk-NL-prop on each of these lines's EOL. - (while (< (point) pos) ; one content-free line each iteration. - (cond ; recalculate nl-prop from previous line's value. - ((memq nl-prop '(?\; nil)) (setq nl-prop ?\#)) - ((eq nl-prop ?\\) - (if (not (looking-at "[ \t]*\\\\$")) (setq nl-prop ?\;))) ; was ?\# 2002/10/25 - ;; ?\# (empty line) and ?\{ (open stmt) don't change. - ) - (forward-line) - (c-put-char-property (1- (point)) 'c-awk-NL-prop nl-prop)) - nl-prop)))) - -(defun c-awk-get-NL-prop-prev-line (&optional do-lim) - ;; Get the c-awk-NL-prop text-property from the previous line, calculating - ;; it if necessary. Return nil iff we're already at BOB. - ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. - (if (bobp) - nil - (or (c-get-char-property (c-point 'eopl) 'c-awk-NL-prop) - (c-awk-calculate-NL-prop-prev-line do-lim)))) - -(defun c-awk-get-NL-prop-cur-line (&optional do-lim) - ;; Get the c-awk-NL-prop text-property from the current line, calculating it - ;; if necessary. (As a special case, the property doesn't get set on an - ;; empty line at EOB (there's no position to set the property on), but the - ;; function returns the property value an EOL would have got.) - ;; - ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. - (save-excursion - (let ((extra-nl nil)) - (end-of-line) ; Necessary for the following test to work. - (when (= (forward-line) 1) ; if we were on the last line.... - (insert-char ?\n 1) ; ...artificial eol is needed for comment detection. - (setq extra-nl t)) - (prog1 (c-awk-get-NL-prop-prev-line do-lim) - (if extra-nl (delete-backward-char 1)))))) - -(defun c-awk-prev-line-incomplete-p (&optional do-lim) - ;; Is there an incomplete statement at the end of the previous line? - ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. - (memq (c-awk-get-NL-prop-prev-line do-lim) '(?\\ ?\{))) - -(defun c-awk-cur-line-incomplete-p (&optional do-lim) - ;; Is there an incomplete statement at the end of the current line? - ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. - (memq (c-awk-get-NL-prop-cur-line do-lim) '(?\\ ?\{))) - -(defun c-awk-completed-stmt-ws-ends-prev-line-p (&optional do-lim) - ;; Is there a termination of a statement as the last thing (apart from an - ;; optional comment) on the previous line? - ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. - (eq (c-awk-get-NL-prop-prev-line do-lim) ?\;)) - -(defun c-awk-completed-stmt-ws-ends-line-p (&optional pos do-lim) - ;; Same as previous function, but for the line containing position POS (or - ;; the current line if POS is omitted). - ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. - (save-excursion - (if pos (goto-char pos)) - (eq (c-awk-get-NL-prop-cur-line do-lim) ?\;))) - -(defun c-awk-after-logical-semicolon (&optional do-lim) -;; Are we at BOL, the preceding EOL being a "logical semicolon"? -;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. - (and (bolp) - (eq (c-awk-get-NL-prop-prev-line do-lim) ?\;))) - -(defun c-awk-backward-syntactic-ws (&optional lim) -;; Skip backwards over awk-syntactic whitespace. This is whitespace -;; characters, comments, and NEWLINES WHICH AREN'T "VIRTUAL SEMICOLONS". For -;; this function, a newline isn't a "virtual semicolon" if that line ends with -;; a real semicolon (or closing brace). -;; However if point starts inside a comment or preprocessor directive, the -;; content of it is not treated as whitespace. LIM (optional) sets a limit on -;; the backward movement. - (let ((lim (or lim (point-min))) - after-real-br) - (c-backward-syntactic-ws (max lim (c-point 'bol))) - (while ; go back one WS line each time round this loop. - (and (bolp) - (> (point) lim) - (/= (c-awk-get-NL-prop-prev-line) ?\;) - (/= (point) - ;; The following function requires point at BONL [not EOL] to - ;; recognise a preceding comment,. - (progn (c-backward-syntactic-ws (max lim (c-point 'bopl))) - (point))))) - ;; Does the previous line end with a real ; or }? If so, go back to it. - (if (and (bolp) - (eq (c-awk-get-NL-prop-prev-line) ?\;) - (save-excursion - (c-backward-syntactic-ws (max lim (c-point 'bopl))) - (setq after-real-br (point)) - (c-awk-after-rbrace-or-statement-semicolon))) - (goto-char after-real-br)))) - -(defun c-awk-NL-prop-not-set () - ;; Is the NL-prop on the current line either nil or unset? - (not (c-get-char-property (c-point 'eol) 'c-awk-NL-prop))) - -(defun c-awk-clear-NL-props (beg end) - ;; This function is run from before-change-hooks. It clears the - ;; c-awk-NL-prop text property from beg to the end of the buffer (The END - ;; parameter is ignored). This ensures that the indentation engine will - ;; never use stale values for this property. - (save-restriction - (widen) - (c-clear-char-properties beg (point-max) 'c-awk-NL-prop))) - -(defun c-awk-unstick-NL-prop () - ;; Ensure that the text property c-awk-NL-prop is "non-sticky". Without - ;; this, a new newline inserted after an old newline (e.g. by C-j) would - ;; inherit any c-awk-NL-prop from the old newline. This would be a Bad - ;; Thing. This function's action is required by c-put-char-property. - (if (and (boundp 'text-property-default-nonsticky) ; doesn't exist in Xemacs - (not (assoc 'c-awk-NL-prop text-property-default-nonsticky))) - (setq text-property-default-nonsticky - (cons '(c-awk-NL-prop . t) text-property-default-nonsticky)))) - -;; The following is purely a diagnostic command, to be commented out of the -;; final release. ACM, 2002/6/1 -;; (defun NL-props () -;; (interactive) -;; (let (pl-prop cl-prop) -;; (message "Prev-line: %s Cur-line: %s" -;; (if (setq pl-prop (c-get-char-property (c-point 'eopl) 'c-awk-NL-prop)) -;; (char-to-string pl-prop) -;; "nil") -;; (if (setq cl-prop (c-get-char-property (c-point 'eol) 'c-awk-NL-prop)) -;; (char-to-string cl-prop) -;; "nil")))) -;(define-key awk-mode-map [?\C-c ?\r] 'NL-props) ; commented out, 2002/8/31 -;for now. In the byte compiled version, this causes things to crash because -;awk-mode-map isn't yet defined. :-( - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; The following section of the code is to do with font-locking. The biggest -;; problem for font-locking is deciding whether a / is a regular expression -;; delimiter or a division sign - determining precisely where strings and -;; regular expressions start and stop is also troublesome. This is the -;; purpose of the function c-awk-set-syntax-table-properties and the myriad -;; elisp regular expressions it uses. -;; -;; Because AWK is a line oriented language, I felt the normal cc-mode strategy -;; for font-locking unterminated strings (i.e. font-locking the buffer up to -;; the next string delimiter as a string) was inappropriate. Instead, -;; unbalanced string/regexp delimiters are given the warning font, being -;; refonted with the string font as soon as the matching delimiter is entered. -;; -;; This requires the region processed by the current font-lock after-change -;; function to have access to the start of the string/regexp, which may be -;; several lines back. The elisp "advice" feature is used on these functions -;; to allow this. - -(defun c-awk-beginning-of-logical-line (&optional pos) -;; Go back to the start of the (apparent) current line (or the start of the -;; line containing POS), returning the buffer position of that point. I.e., -;; go back to the last line which doesn't have an escaped EOL before it. -;; -;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any -;; comment, string or regexp. IT MAY WELL BE that this function should not be -;; executed on a narrowed buffer. - (if pos (goto-char pos)) - (forward-line 0) - (while (and (> (point) (point-min)) - (eq (char-before (1- (point))) ?\\)) - (forward-line -1)) - (point)) - -(defun c-awk-end-of-logical-line (&optional pos) -;; Go forward to the end of the (apparent) current logical line (or the end of -;; the line containing POS), returning the buffer position of that point. I.e., -;; go to the end of the next line which doesn't have an escaped EOL. -;; -;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any -;; comment, string or regexp. IT MAY WELL BE that this function should not be -;; executed on a narrowed buffer. - (if pos (goto-char pos)) - (end-of-line) - (while (and (< (point) (point-max)) - (eq (char-before) ?\\)) - (end-of-line 2)) - (point)) + +;; This section defines regular expressions used in the analysis of AWK code. ;; N.B. In the following regexps, an EOL is either \n OR \r. This is because ;; Emacs has in the past used \r to mark hidden lines in some fashion (and @@ -464,6 +95,8 @@ (defconst c-awk-esc-pair-re "\\\\\\(.\\|\n\\|\r\\|\\'\\)") ;; Matches any escaped (with \) character-pair, including an escaped newline. +(defconst c-awk-non-eol-esc-pair-re "\\\\\\(.\\|\\'\\)") +;; Matches any escaped (with \) character-pair, apart from an escaped newline. (defconst c-awk-comment-without-nl "#.*") ;; Matches an AWK comment, not including the terminating NL (if any). Note ;; that the "enclosing" (elisp) regexp must ensure the # is real. @@ -471,7 +104,8 @@ ;; Matches a newline, or the end of buffer. ;; "Space" regular expressions. -(defconst c-awk-escaped-nl "\\\\[\n\r]") +(eval-and-compile + (defconst c-awk-escaped-nl "\\\\[\n\r]")) ;; Matches an escaped newline. (defconst c-awk-escaped-nls* (concat "\\(" c-awk-escaped-nl "\\)*")) ;; Matches a possibly empty sequence of escaped newlines. Used in @@ -480,10 +114,15 @@ ;; (concat "\\(" c-awk-escaped-nls* "\\|" "[ \t]+" "\\)*")) ;; The above RE was very slow. It's runtime was doubling with each additional ;; space :-( Reformulate it as below: -(defconst c-awk-escaped-nls*-with-space* - (concat "\\(" c-awk-escaped-nl "\\|" "[ \t]" "\\)*")) +(eval-and-compile + (defconst c-awk-escaped-nls*-with-space* + (concat "\\(" c-awk-escaped-nl "\\|" "[ \t]" "\\)*"))) ;; Matches a possibly empty sequence of escaped newlines with optional ;; interspersed spaces and tabs. Used in awk-font-lock-keywords. +(defconst c-awk-blank-or-comment-line-re + (concat "[ \t]*\\(#\\|\\\\?$\\)")) +;; Matche (the tail of) a line containing at most either a comment or an +;; escaped EOL. ;; REGEXPS FOR "HARMLESS" STRINGS/LINES. (defconst c-awk-harmless-char-re "[^_#/\"\\\\\n\r]") @@ -521,6 +160,9 @@ (concat "\\=_?\"" c-awk-string-innards-re)) ;; Matches an AWK string at point up to, but not including, any terminator. ;; A gawk 3.1+ string may look like _"localisable string". +(defconst c-awk-one-line-possibly-open-string-re + (concat "\"\\(" c-awk-string-ch-re "\\|" c-awk-non-eol-esc-pair-re "\\)*" + "\\(\"\\|\\\\?$\\|\\'\\)")) ;; REGEXPS FOR AWK REGEXPS. (defconst c-awk-regexp-normal-re "[^[/\\\n\r]") @@ -541,13 +183,25 @@ "\\|" "[^]\n\r]" "\\)*" "\\(]\\|$\\)")) ;; Matches a regexp char list, up to (but not including) EOL if the ] is ;; missing. +(defconst c-awk-regexp-one-line-possibly-open-char-list-re + (concat "\\[\\]?\\(" c-awk-non-eol-esc-pair-re "\\|" "[^]\n\r]" "\\)*" + "\\(]\\|\\\\?$\\|\\'\\)")) +;; Matches the head (or all) of a regexp char class, up to (but not +;; including) the first EOL. (defconst c-awk-regexp-innards-re (concat "\\(" c-awk-esc-pair-re "\\|" c-awk-regexp-char-list-re "\\|" c-awk-regexp-normal-re "\\)*")) ;; Matches the inside of an AWK regexp (i.e. without the enclosing /s) (defconst c-awk-regexp-without-end-re (concat "/" c-awk-regexp-innards-re)) -;; Matches an AWK regexp up to, but not including, any terminating /. +;; Matches an AWK regexp up to, but not including, any terminating /. +(defconst c-awk-one-line-possibly-open-regexp-re + (concat "/\\(" c-awk-non-eol-esc-pair-re + "\\|" c-awk-regexp-one-line-possibly-open-char-list-re + "\\|" c-awk-regexp-normal-re "\\)*" + "\\(/\\|\\\\?$\\|\\'\\)")) +;; Matches as much of the head of an AWK regexp which fits on one line, +;; possibly all of it. ;; REGEXPS used for scanning an AWK buffer in order to decide IF A '/' IS A ;; REGEXP OPENER OR A DIVISION SIGN. By "state" in the following is meant @@ -587,6 +241,405 @@ ;; will only work when there won't be a preceding " or / before the sought / ;; to foul things up. +;; REGEXPS USED FOR FINDING THE POSITION OF A "virtual semicolon" +(defconst c-awk-_-harmless-nonws-char-re "[^#/\"\\\\\n\r \t]") +;;;; NEW VERSION! (which will be restricted to the current line) +(defconst c-awk-one-line-non-syn-ws*-re + (concat "\\([ \t]*" + "\\(" c-awk-_-harmless-nonws-char-re "\\|" + c-awk-non-eol-esc-pair-re "\\|" + c-awk-one-line-possibly-open-string-re "\\|" + c-awk-one-line-possibly-open-regexp-re + "\\)" + "\\)*")) + + +;; ACM, 2002/5/29: +;; +;; The next section of code is about determining whether or not an AWK +;; statement is complete or not. We use this to indent the following line. +;; The determination is pretty straightforward in C, where a statement ends +;; with either a ; or a }. Only "while" really gives any trouble there, since +;; it might be the end of a do-while. In AWK, on the other hand, semicolons +;; are rarely used, and EOLs _usually_ act as "virtual semicolons". In +;; addition, we have the complexity of escaped EOLs. The core of this +;; analysis is in the middle of the function +;; c-awk-calculate-NL-prop-prev-line, about 130 lines lower down. +;; +;; To avoid continually repeating this expensive analysis, we "cache" its +;; result in a text-property, c-awk-NL-prop, whose value for a line is set on +;; the EOL (if any) which terminates that line. Should the property be +;; required for the very last line (which has no EOL), it is calculated as +;; required but not cached. The c-awk-NL-prop property should be thought of +;; as only really valid immediately after a buffer change, not a permanently +;; set property. (By contrast, the syntax-table text properties (set by an +;; after-change function) must be constantly updated for the mode to work +;; properly). +;; +;; This text property is also used for "syntactic whitespace" movement, this +;; being where the distinction between the values '$' and '}' is significant. +;; +;; The valid values for c-awk-NL-prop are: +;; +;; nil The property is not currently set for this line. +;; '#' There is NO statement on this line (at most a comment), and no open +;; statement from a previous line which could have been completed on this +;; line. +;; '{' There is an unfinished statement on this (or a previous) line which +;; doesn't require \s to continue onto another line, e.g. the line ends +;; with {, or the && operator, or "if (condition)". Note that even if the +;; newline is redundantly escaped, it remains a '{' line. +;; '\' There is an escaped newline at the end of this line and this '\' is +;; essential to the syntax of the program. (i.e. if it had been a +;; frivolous \, it would have been ignored and the line been given one of +;; the other property values.) +;; '$' A non-empty statement is terminated on the line by an EOL (a "virtual +;; semicolon"). This might be a content-free line terminating a statement +;; from the preceding (continued) line (which has property \). +;; '}' A statement, being the last thing (aside from ws/comments) is +;; explicitly terminated on this line by a closing brace (or sometimes a +;; semicolon). +;; +;; This set of values has been chosen so that the property's value on a line +;; is completely determined by the contents of the line and the property on +;; the previous line, EXCEPT for where a "while" might be the closing +;; statement of a do-while. + +(defun c-awk-after-if-for-while-condition-p (&optional do-lim) + ;; Are we just after the ) in "if/for/while ()"? + ;; + ;; Note that the end of the ) in a do .... while () doesn't + ;; count, since the purpose of this routine is essentially to decide + ;; whether to indent the next line. + ;; + ;; DO-LIM sets a limit on how far back we search for the "do" of a possible + ;; do-while. + ;; + ;; This function might do hidden buffer changes. + (and + (eq (char-before) ?\)) + (save-excursion + (let ((par-pos (c-safe (scan-lists (point) -1 0)))) + (when par-pos + (goto-char par-pos) ; back over "(...)" + (c-backward-token-1) ; BOB isn't a problem. + (or (looking-at "\\(if\\|for\\)\\>\\([^_]\\|$\\)") + (and (looking-at "while\\>\\([^_]\\|$\\)") ; Ensure this isn't a do-while. + (not (eq (c-beginning-of-statement-1 do-lim) + 'beginning))))))))) + +(defun c-awk-after-function-decl-param-list () + ;; Are we just after the ) in "function foo (bar)" ? + ;; + ;; This function might do hidden buffer changes. + (and (eq (char-before) ?\)) + (save-excursion + (let ((par-pos (c-safe (scan-lists (point) -1 0)))) + (when par-pos + (goto-char par-pos) ; back over "(...)" + (c-backward-token-1) ; BOB isn't a problem + (and (looking-at "[_a-zA-Z][_a-zA-Z0-9]*\\>") + (progn (c-backward-token-1) + (looking-at "func\\(tion\\)?\\>")))))))) + +;; 2002/11/8: FIXME! Check c-backward-token-1/2 for success (0 return code). +(defun c-awk-after-continue-token () +;; Are we just after a token which can be continued onto the next line without +;; a backslash? +;; +;; This function might do hidden buffer changes. + (save-excursion + (c-backward-token-1) ; FIXME 2002/10/27. What if this fails? + (if (and (looking-at "[&|]") (not (bobp))) + (backward-char)) ; c-backward-token-1 doesn't do this :-( + (looking-at "[,{?:]\\|&&\\|||\\|do\\>\\|else\\>"))) + +(defun c-awk-after-rbrace-or-statement-semicolon () + ;; Are we just after a } or a ; which closes a statement? + ;; Be careful about ;s in for loop control bits. They don't count! + ;; + ;; This function might do hidden buffer changes. + (or (eq (char-before) ?\}) + (and + (eq (char-before) ?\;) + (save-excursion + (let ((par-pos (c-safe (scan-lists (point) -1 1)))) + (when par-pos + (goto-char par-pos) ; go back to containing ( + (not (and (looking-at "(") + (c-backward-token-1) ; BOB isn't a problem + (looking-at "for\\>"))))))))) + +(defun c-awk-back-to-contentful-text-or-NL-prop () + ;; Move back to just after the first found of either (i) an EOL which has + ;; the c-awk-NL-prop text-property set; or (ii) non-ws text; or (iii) BOB. + ;; We return either the value of c-awk-NL-prop (in case (i)) or nil. + ;; Calling functions can best distinguish cases (ii) and (iii) with (bolp). + ;; + ;; Note that an escaped eol counts as whitespace here. + ;; + ;; Kludge: If c-backward-syntactic-ws gets stuck at a BOL, it is likely + ;; that the previous line contains an unterminated string (without \). In + ;; this case, assume that the previous line's c-awk-NL-prop is a $. + ;; + ;; POINT MUST BE AT THE START OF A LINE when calling this function. This + ;; is to ensure that the various backward-comment functions will work + ;; properly. + ;; + ;; This function might do hidden buffer changes. + (let ((nl-prop nil) + bol-pos bsws-pos) ; starting pos for a backward-syntactic-ws call. + (while ;; We are at a BOL here. Go back one line each iteration. + (and + (not (bobp)) + (not (setq nl-prop (c-get-char-property (1- (point)) 'c-awk-NL-prop))) + (progn (setq bol-pos (c-point 'bopl)) + (setq bsws-pos (point)) + ;; N.B. the following function will not go back past an EOL if + ;; there is an open string (without \) on the previous line. + ;; If we find such, set the c-awk-NL-prop on it, too + ;; (2004/3/29). + (c-backward-syntactic-ws bol-pos) + (or (/= (point) bsws-pos) + (progn (setq nl-prop ?\$) + (c-put-char-property (1- (point)) 'c-awk-NL-prop nl-prop) + nil))) + ;; If we had a backslash at EOL, c-backward-syntactic-ws will + ;; have gone backwards over it. Check the backslash was "real". + (progn + (if (looking-at "[ \t]*\\\\+$") + (if (progn + (end-of-line) + (search-backward-regexp + "\\(^\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\$" ; ODD number of \s at EOL :-) + bol-pos t)) + (progn (end-of-line) ; escaped EOL. + (backward-char) + (c-backward-syntactic-ws bol-pos)) + (end-of-line))) ; The \ at eol is a fake. + (bolp)))) + nl-prop)) + +(defun c-awk-calculate-NL-prop-prev-line (&optional do-lim) + ;; Calculate and set the value of the c-awk-NL-prop on the immediately + ;; preceding EOL. This may also involve doing the same for several + ;; preceding EOLs. + ;; + ;; NOTE that if the property was already set, we return it without + ;; recalculation. (This is by accident rather than design.) + ;; + ;; Return the property which got set (or was already set) on the previous + ;; line. Return nil if we hit BOB. + ;; + ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. + ;; + ;; This function might do hidden buffer changes. + (save-excursion + (save-match-data + (beginning-of-line) + (let* ((pos (point)) + (nl-prop (c-awk-back-to-contentful-text-or-NL-prop))) + ;; We are either (1) at a BOL (with nl-prop containing the previous + ;; line's c-awk-NL-prop) or (2) after contentful text on a line. At + ;; the BOB counts as case (1), so we test next for bolp rather than + ;; non-nil nl-prop. + (when (not (bolp)) + (setq nl-prop + (cond + ;; Incomplete statement which doesn't require escaped EOL? + ((or (c-awk-after-if-for-while-condition-p do-lim) + (c-awk-after-function-decl-param-list) + (c-awk-after-continue-token)) + ?\{) + ;; Escaped EOL (where there's also something to continue)? + ((and (looking-at "[ \t]*\\\\$") + (not (c-awk-after-rbrace-or-statement-semicolon))) + ?\\) + ;; A statement was completed on this line. How? + ((memq (char-before) '(?\; ?\})) ?\}) ; Real ; or } + (t ?\$))) ; A virtual semicolon. + (end-of-line) + (c-put-char-property (point) 'c-awk-NL-prop nl-prop) + (forward-line)) + + ;; We are now at a (possibly empty) sequence of content-free lines. + ;; Set c-awk-NL-prop on each of these lines's EOL. + (while (< (point) pos) ; one content-free line each iteration. + (cond ; recalculate nl-prop from previous line's value. + ((memq nl-prop '(?\} ?\$ nil)) (setq nl-prop ?\#)) + ((eq nl-prop ?\\) + (if (not (looking-at "[ \t]*\\\\$")) (setq nl-prop ?\$))) + ;; ?\# (empty line) and ?\{ (open stmt) don't change. + ) + (forward-line) + (c-put-char-property (1- (point)) 'c-awk-NL-prop nl-prop)) + nl-prop)))) + +(defun c-awk-get-NL-prop-prev-line (&optional do-lim) + ;; Get the c-awk-NL-prop text-property from the previous line, calculating + ;; it if necessary. Return nil iff we're already at BOB. + ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. + ;; + ;; This function might do hidden buffer changes. + (if (bobp) + nil + (or (c-get-char-property (c-point 'eopl) 'c-awk-NL-prop) + (c-awk-calculate-NL-prop-prev-line do-lim)))) + +(defun c-awk-get-NL-prop-cur-line (&optional do-lim) + ;; Get the c-awk-NL-prop text-property from the current line, calculating it + ;; if necessary. (As a special case, the property doesn't get set on an + ;; empty line at EOB (there's no position to set the property on), but the + ;; function returns the property value an EOL would have got.) + ;; + ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. + ;; + ;; This function might do hidden buffer changes. + (save-excursion + (let ((extra-nl nil)) + (end-of-line) ; Necessary for the following test to work. + (when (= (forward-line) 1) ; if we were on the last line.... + (insert-char ?\n 1) ; ...artificial eol is needed for comment detection. + (setq extra-nl t)) + (prog1 (c-awk-get-NL-prop-prev-line do-lim) + (if extra-nl (delete-backward-char 1)))))) + +(defsubst c-awk-prev-line-incomplete-p (&optional do-lim) + ;; Is there an incomplete statement at the end of the previous line? + ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. + ;; + ;; This function might do hidden buffer changes. + (memq (c-awk-get-NL-prop-prev-line do-lim) '(?\\ ?\{))) + +(defsubst c-awk-cur-line-incomplete-p (&optional do-lim) + ;; Is there an incomplete statement at the end of the current line? + ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. + ;; + ;; This function might do hidden buffer changes. + (memq (c-awk-get-NL-prop-cur-line do-lim) '(?\\ ?\{))) + +;;;; NOTES ON "VIRTUAL SEMICOLONS" +;;;; +;;;; A "virtual semicolon" is what terminates a statement when there is no ; +;;;; or } to do the job. Like point, it is considered to lie _between_ two +;;;; characters. As from mid-March 2004, it is considered to lie just after +;;;; the last non-syntactic-whitespace character on the line; (previously, it +;;;; was considered an attribute of the EOL on the line). A real semicolon +;;;; never counts as a virtual one. + +(defun c-awk-at-vsemi-p (&optional pos) + ;; Is there a virtual semicolon at POS (or POINT)? + (save-excursion + (let (nl-prop + (pos-or-point (progn (if pos (goto-char pos)) (point)))) + (forward-line 0) + (search-forward-regexp c-awk-one-line-non-syn-ws*-re) + (and (eq (point) pos-or-point) + (progn + (while (and (eq (setq nl-prop (c-awk-get-NL-prop-cur-line)) ?\\) + (eq (forward-line) 0) + (looking-at c-awk-blank-or-comment-line-re))) + (eq nl-prop ?\$)))))) + +(defun c-awk-vsemi-status-unknown-p () + ;; Are we unsure whether there is a virtual semicolon on the current line? + ;; DO NOT under any circumstances attempt to calculate this; that would + ;; defeat the (admittedly kludgey) purpose of this function, which is to + ;; prevent an infinite recursion in c-beginning-of-statement-1 when point + ;; starts at a `while' token. + (not (c-get-char-property (c-point 'eol) 'c-awk-NL-prop))) + +(defun c-awk-clear-NL-props (beg end) + ;; This function is run from before-change-hooks. It clears the + ;; c-awk-NL-prop text property from beg to the end of the buffer (The END + ;; parameter is ignored). This ensures that the indentation engine will + ;; never use stale values for this property. + ;; + ;; This function might do hidden buffer changes. + (save-restriction + (widen) + (c-clear-char-properties beg (point-max) 'c-awk-NL-prop))) + +(defun c-awk-unstick-NL-prop () + ;; Ensure that the text property c-awk-NL-prop is "non-sticky". Without + ;; this, a new newline inserted after an old newline (e.g. by C-j) would + ;; inherit any c-awk-NL-prop from the old newline. This would be a Bad + ;; Thing. This function's action is required by c-put-char-property. + (if (and (boundp 'text-property-default-nonsticky) ; doesn't exist in Xemacs + (not (assoc 'c-awk-NL-prop text-property-default-nonsticky))) + (setq text-property-default-nonsticky + (cons '(c-awk-NL-prop . t) text-property-default-nonsticky)))) + +;; The following is purely a diagnostic command, to be commented out of the +;; final release. ACM, 2002/6/1 +;; (defun NL-props () +;; (interactive) +;; (let (pl-prop cl-prop) +;; (message "Prev-line: %s Cur-line: %s" +;; (if (setq pl-prop (c-get-char-property (c-point 'eopl) 'c-awk-NL-prop)) +;; (char-to-string pl-prop) +;; "nil") +;; (if (setq cl-prop (c-get-char-property (c-point 'eol) 'c-awk-NL-prop)) +;; (char-to-string cl-prop) +;; "nil")))) +;(define-key awk-mode-map [?\C-c ?\r] 'NL-props) ; commented out, 2002/8/31 +;for now. In the byte compiled version, this causes things to crash because +;awk-mode-map isn't yet defined. :-( + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; The following section of the code is to do with font-locking. The biggest +;; problem for font-locking is deciding whether a / is a regular expression +;; delimiter or a division sign - determining precisely where strings and +;; regular expressions start and stop is also troublesome. This is the +;; purpose of the function c-awk-set-syntax-table-properties and the myriad +;; elisp regular expressions it uses. +;; +;; Because AWK is a line oriented language, I felt the normal cc-mode strategy +;; for font-locking unterminated strings (i.e. font-locking the buffer up to +;; the next string delimiter as a string) was inappropriate. Instead, +;; unbalanced string/regexp delimiters are given the warning font, being +;; refonted with the string font as soon as the matching delimiter is entered. +;; +;; This requires the region processed by the current font-lock after-change +;; function to have access to the start of the string/regexp, which may be +;; several lines back. The elisp "advice" feature is used on these functions +;; to allow this. + +(defun c-awk-beginning-of-logical-line (&optional pos) +;; Go back to the start of the (apparent) current line (or the start of the +;; line containing POS), returning the buffer position of that point. I.e., +;; go back to the last line which doesn't have an escaped EOL before it. +;; +;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any +;; comment, string or regexp. IT MAY WELL BE that this function should not be +;; executed on a narrowed buffer. +;; +;; This function might do hidden buffer changes. + (if pos (goto-char pos)) + (forward-line 0) + (while (and (> (point) (point-min)) + (eq (char-before (1- (point))) ?\\)) + (forward-line -1)) + (point)) + +(defun c-awk-end-of-logical-line (&optional pos) +;; Go forward to the end of the (apparent) current logical line (or the end of +;; the line containing POS), returning the buffer position of that point. I.e., +;; go to the end of the next line which doesn't have an escaped EOL. +;; +;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any +;; comment, string or regexp. IT MAY WELL BE that this function should not be +;; executed on a narrowed buffer. +;; +;; This function might do hidden buffer changes. + (if pos (goto-char pos)) + (end-of-line) + (while (and (< (point) (point-max)) + (eq (char-before) ?\\)) + (end-of-line 2)) + (point)) + ;; ACM, 2002/02/15: The idea of the next function is to put the "Error font" ;; on strings/regexps which are missing their closing delimiter. ;; 2002/4/28. The default syntax for / has been changed from "string" to @@ -605,24 +658,26 @@ ;; ;; If the closing delimiter is missing (i.e., there is an EOL there) set the ;; STRING-FENCE property on the opening " or / and closing EOL. +;; +;; This function does hidden buffer changes. (if (eq (char-after beg) ?_) (setq beg (1+ beg))) ;; First put the properties on the delimiters. (cond ((eq end (point-max)) ; string/regexp terminated by EOB - (put-text-property beg (1+ beg) 'syntax-table '(15))) ; (15) = "string fence" + (c-put-char-property beg 'syntax-table '(15))) ; (15) = "string fence" ((/= (char-after beg) (char-after end)) ; missing end delimiter - (put-text-property beg (1+ beg) 'syntax-table '(15)) - (put-text-property end (1+ end) 'syntax-table '(15))) + (c-put-char-property beg 'syntax-table '(15)) + (c-put-char-property end 'syntax-table '(15))) ((eq (char-after beg) ?/) ; Properly bracketed regexp - (put-text-property beg (1+ beg) 'syntax-table '(7)) ; (7) = "string" - (put-text-property end (1+ end) 'syntax-table '(7))) + (c-put-char-property beg 'syntax-table '(7)) ; (7) = "string" + (c-put-char-property end 'syntax-table '(7))) (t)) ; Properly bracketed string: Nothing to do. ;; Now change the properties of any escaped "s in the string to punctuation. (save-excursion (goto-char (1+ beg)) (or (eobp) (while (search-forward "\"" end t) - (put-text-property (1- (point)) (point) 'syntax-table '(1)))))) + (c-put-char-property (1- (point)) 'syntax-table '(1)))))) (defun c-awk-syntax-tablify-string () ;; Point is at the opening " or _" of a string. Set the syntax-table @@ -630,6 +685,8 @@ ;; ;; The result is nil if a / immediately after the string would be a regexp ;; opener, t if it would be a division sign. + ;; + ;; This function does hidden buffer changes. (search-forward-regexp c-awk-string-without-end-here-re nil t) ; a (possibly unterminated) string (c-awk-set-string-regexp-syntax-table-properties (match-beginning 0) (match-end 0)) @@ -653,6 +710,8 @@ ;; point is. ;; ;; The result is what ANCHOR-STATE-/DIV (see above) is where point is left. + ;; + ;; This function might do hidden buffer changes. (let ((/point (point))) (goto-char anchor) ;; Analyse the line to find out what the / is. @@ -698,14 +757,18 @@ ;; given the property "punctuation". This will later allow other routines ;; to use the regexp "\\S\"*" to skip over the string innards. ;; (iv) Inside a comment, all syntax-table properties are cleared. +;; +;; This function does hidden buffer changes. (let (anchor (anchor-state-/div nil)) ; t means a following / would be a div sign. (c-awk-beginning-of-logical-line) ; ACM 2002/7/21. This is probably redundant. - (put-text-property (point) lim 'syntax-table nil) - (search-forward-regexp c-awk-harmless-lines+-here-re nil t) ; skip harmless lines. - + (c-clear-char-properties (point) lim 'syntax-table) ;; Once round the next loop for each string, regexp, or div sign - (while (< (point) lim) + (while (progn + ;; Skip any "harmless" lines before the next tricky one. + (if (search-forward-regexp c-awk-harmless-lines+-here-re nil t) + (setq anchor-state-/div nil)) + (< (point) lim)) (setq anchor (point)) (search-forward-regexp c-awk-harmless-string*-here-re nil t) ;; We are now looking at either a " or a /. @@ -713,11 +776,7 @@ (setq anchor-state-/div (if (looking-at "_?\"") (c-awk-syntax-tablify-string) - (c-awk-syntax-tablify-/ anchor anchor-state-/div))) - - ;; Skip any further "harmless" lines before the next tricky one. - (if (search-forward-regexp c-awk-harmless-lines+-here-re nil t) - (setq anchor-state-/div nil))) + (c-awk-syntax-tablify-/ anchor anchor-state-/div)))) nil)) @@ -734,6 +793,8 @@ ;; This function is called exclusively from the before-change-functions hook. ;; It does two things: Finds the end of the (logical) line on which END lies, ;; and clears c-awk-NL-prop text properties from this point onwards. +;; +;; This function might do hidden buffer changes. (save-restriction (save-excursion (setq c-awk-old-EOLL (c-awk-end-of-logical-line end)) @@ -745,6 +806,8 @@ ;; This is the end of the logical line on which the change happened, either ;; as it was before the change, or as it is now, which ever is later. ;; N.B. point is left undefined. + ;; + ;; This function might do hidden buffer changes. (max (+ (- c-awk-old-EOLL old-len) (- end beg)) (c-awk-end-of-logical-line end))) @@ -754,6 +817,8 @@ ;; changed region. However, if font-lock is enabled, this function does ;; nothing, since an enabled font-lock after-change function will always do ;; this. +;; +;; This function might do hidden buffer changes. (unless (and (boundp 'font-lock-mode) font-lock-mode) (save-restriction (save-excursion @@ -786,10 +851,14 @@ (c-awk-advise-fl-for-awk-region lazy-lock-defer-rest-after-change) (c-awk-advise-fl-for-awk-region lazy-lock-defer-line-after-change) -;; ACM 2002/9/29. Functions for C-M-a and C-M-e + +;; ACM 2002/9/29. Movement functions, e.g. for C-M-a and C-M-e +;; The following three regexps differ from those earlier on in cc-awk.el in +;; that they assume the syntax-table properties have been set. They are thus +;; not useful for code which sets these properties. (defconst c-awk-terminated-regexp-or-string-here-re "\\=\\s\"\\S\"*\\s\"") -;; Matches a terminated string/regexp (utilising syntax-table properties). +;; Matches a terminated string/regexp. (defconst c-awk-unterminated-regexp-or-string-here-re "\\=\\s|\\S|*$") ;; Matches an unterminated string/regexp, NOT including the eol at the end. @@ -798,6 +867,21 @@ (concat "\\([^{;#/\"\\\\\n\r]\\|" c-awk-esc-pair-re "\\)*")) ;; Matches any "harmless" character in a pattern or an escaped character pair. +(defun c-awk-at-statement-end-p () + ;; Point is not inside a comment or string. Is it AT the end of a + ;; statement? This means immediately after the last non-ws character of the + ;; statement. The caller is responsible for widening the buffer, if + ;; appropriate. + (and (not (bobp)) + (save-excursion + (backward-char) + (or (looking-at "[};]") + (and (memq (c-awk-get-NL-prop-cur-line) '(?\$ ?\\)) + (looking-at + (eval-when-compile + (concat "[^ \t\n\r\\]" c-awk-escaped-nls*-with-space* + "[#\n\r]")))))))) + (defun c-awk-beginning-of-defun (&optional arg) "Move backward to the beginning of an AWK \"defun\". With ARG, do it that many times. Negative arg -N means move forward to Nth following beginning of @@ -807,7 +891,10 @@ of a defun is recognized as code starting at column zero which is neither a closing brace nor a comment nor a continuation of the previous line. Unlike in some other modes, having an opening brace at column 0 is neither necessary -nor helpful." +nor helpful. + +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." (interactive "p") (save-match-data (c-save-buffer-state ; ensures the buffer is writable. @@ -820,14 +907,14 @@ ;; is genuinely a beginning-of-defun. (while (and (setq found (search-backward-regexp "^[^#} \t\n\r]" (point-min) 'stop-at-limit)) - (not (memq (c-awk-get-NL-prop-prev-line) '(?\; ?\#))))) + (not (memq (c-awk-get-NL-prop-prev-line) '(?\$ ?\} ?\#))))) (setq arg (1- arg))) ;; The same for a -ve arg. (if (not (eq (point) (point-max))) (forward-char 1)) (while (and found (< arg 0) (not (eq (point) (point-max)))) ; The same for -ve arg. (while (and (setq found (search-forward-regexp "^[^#} \t\n\r]" (point-max) 'stop-at-limit)) - (not (memq (c-awk-get-NL-prop-prev-line) '(?\; ?\#))))) + (not (memq (c-awk-get-NL-prop-prev-line) '(?\$ ?\} ?\#))))) (setq arg (1+ arg))) (if found (goto-char (match-beginning 0)))) (eq arg 0))))) @@ -838,6 +925,8 @@ ;; comment. Typically, we stop at the { which denotes the corresponding AWK ;; action/function body. Otherwise we stop at the EOL (or ;) marking the ;; absence of an explicit action. + ;; + ;; This function might do hidden buffer changes. (while (progn (search-forward-regexp c-awk-harmless-pattern-characters*) @@ -855,6 +944,8 @@ (defun c-awk-end-of-defun1 () ;; point is at the start of a "defun". Move to its end. Return end position. + ;; + ;; This function might do hidden buffer changes. (c-awk-forward-awk-pattern) (cond ((looking-at "{") (goto-char (scan-sexps (point) 1))) @@ -866,6 +957,8 @@ (defun c-awk-beginning-of-defun-p () ;; Are we already at the beginning of a defun? (i.e. at code in column 0 ;; which isn't a }, and isn't a continuation line of any sort. + ;; + ;; This function might do hidden buffer changes. (and (looking-at "^[^#} \t\n\r]") (not (c-awk-prev-line-incomplete-p)))) @@ -875,7 +968,10 @@ An end of a defun occurs right after the closing brace that matches the opening brace at its start, or immediately after the AWK pattern when there is -no explicit action; see function `c-awk-beginning-of-defun'." +no explicit action; see function `c-awk-beginning-of-defun'. + +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." (interactive "p") (or arg (setq arg 1)) (save-match-data @@ -911,6 +1007,7 @@ (< arg 0))) (goto-char (min start-point end-point))))))) + (cc-provide 'cc-awk) ; Changed from 'awk-mode, ACM 2002/5/21 ;;; arch-tag: c4836289-3aa4-4a59-9934-9ccc2bacccf3 diff -r 8e25aa911e3e -r 37d0562504bf lisp/progmodes/cc-bytecomp.el --- a/lisp/progmodes/cc-bytecomp.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/progmodes/cc-bytecomp.el Sat Dec 10 21:18:28 2005 +0000 @@ -1,7 +1,7 @@ ;;; cc-bytecomp.el --- compile time setup for proper compilation -;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 -;; Free Software Foundation, Inc. +;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, +;; Inc. ;; Author: Martin Stjernholm ;; Maintainer: bug-cc-mode@gnu.org @@ -22,7 +22,7 @@ ;; 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 +;; along with this program; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. diff -r 8e25aa911e3e -r 37d0562504bf lisp/progmodes/cc-cmds.el --- a/lisp/progmodes/cc-cmds.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/progmodes/cc-cmds.el Sat Dec 10 21:18:28 2005 +0000 @@ -1,6 +1,7 @@ ;;; cc-cmds.el --- user level commands for CC Mode -;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc. +;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, +;; Inc. ;; Authors: 1998- Martin Stjernholm ;; 1992-1999 Barry A. Warsaw @@ -24,7 +25,7 @@ ;; 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 +;; along with this program; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. @@ -45,12 +46,11 @@ (cc-require 'cc-engine) ;; Silence the compiler. -(cc-bytecomp-defvar delete-key-deletes-forward) ; XEmacs 20+ -(cc-bytecomp-defun delete-forward-p) ; XEmacs 21+ -(cc-bytecomp-obsolete-fun insert-and-inherit) ; Marked obsolete in XEmacs 19 +(cc-bytecomp-defun delete-forward-p) ; XEmacs (cc-bytecomp-defvar filladapt-mode) ; c-fill-paragraph contains a kludge ; which looks at this. - +(cc-bytecomp-defun c-forward-subword) +(cc-bytecomp-defun c-backward-subword) (defvar c-fix-backslashes t) @@ -64,8 +64,6 @@ is otherwise empty \(ignoring any line continuation backslash), but that's not done if IGNORE-POINT-POS is non-nil. Returns the amount of indentation change \(in columns)." - ;; - ;; This function does not do any hidden buffer changes. (let ((line-cont-backslash (save-excursion (end-of-line) @@ -134,13 +132,11 @@ shift-amt)) (defun c-newline-and-indent (&optional newline-arg) - "Inserts a newline and indents the new line. + "Insert a newline and indent the new line. This function fixes line continuation backslashes if inside a macro, and takes care to set the indentation before calling `indent-according-to-mode', so that lineup functions like `c-lineup-dont-change' works better." - ;; - ;; This function does not do any hidden buffer changes. ;; TODO: Backslashes before eol in comments and literals aren't ;; kept intact. @@ -221,14 +217,30 @@ (c-save-buffer-state nil (c-guess-basic-syntax))))) (if (not (consp arg)) - (message "syntactic analysis: %s" syntax) + (let (elem pos ols) + (message "Syntactic analysis: %s" syntax) + (unwind-protect + (progn + (while syntax + (setq elem (pop syntax)) + (when (setq pos (c-langelem-pos elem)) + (push (c-put-overlay pos (1+ pos) + 'face 'highlight) + ols)) + (when (setq pos (c-langelem-2nd-pos elem)) + (push (c-put-overlay pos (1+ pos) + 'face 'secondary-selection) + ols))) + (sit-for 10)) + (while ols + (c-delete-overlay (pop ols))))) (indent-for-comment) (insert-and-inherit (format "%s" syntax)) )) (c-keep-region-active)) (defun c-syntactic-information-on-region (from to) - "Inserts a comment with the syntactic analysis on every line in the region." + "Insert a comment with the syntactic analysis on every line in the region." (interactive "*r") (save-excursion (save-restriction @@ -239,6 +251,23 @@ (forward-line))))) +(defun c-update-modeline () + (let ((fmt (format "/%s%s%s%s" + (if c-electric-flag "l" "") + (if (and c-electric-flag c-auto-newline) + "a" "") + (if c-hungry-delete-key "h" "") + (if (and + ;; cc-subword might not be loaded. + (boundp 'c-subword-mode) + (symbol-value 'c-subword-mode)) + "w" + "")))) + (setq c-submode-indicators + (if (> (length fmt) 1) + fmt)) + (force-mode-line-update))) + (defun c-toggle-syntactic-indentation (&optional arg) "Toggle syntactic indentation. Optional numeric ARG, if supplied, turns on syntactic indentation when @@ -249,12 +278,12 @@ functions and the electric keys indent according to the syntactic context keys, when applicable. -When it's turned off, the electric keys does no reindentation, the -indentation functions indents every new line to the same level as the -previous nonempty line, and \\[c-indent-command] adjusts the -indentation in seps specified `c-basic-offset'. The indentation style -has no effect in this mode, nor any of the indentation associated -variables, e.g. `c-special-indent-hook'. +When it's turned off, the electric keys don't reindent, the indentation +functions indents every new line to the same level as the previous +nonempty line, and \\[c-indent-command] adjusts the indentation in steps +specified by `c-basic-offset'. The indentation style has no effect in +this mode, nor any of the indentation associated variables, +e.g. `c-special-indent-hook'. This command sets the variable `c-syntactic-indentation'." (interactive "P") @@ -262,30 +291,36 @@ (c-calculate-state arg c-syntactic-indentation)) (c-keep-region-active)) -(defun c-toggle-auto-state (&optional arg) +(defun c-toggle-auto-newline (&optional arg) "Toggle auto-newline feature. Optional numeric ARG, if supplied, turns on auto-newline when positive, turns it off when negative, and just toggles it when zero or left out. -When the auto-newline feature is enabled (as evidenced by the `/a' or -`/ah' on the modeline after the mode name) newlines are automatically -inserted after special characters such as brace, comma, semi-colon, -and colon." +Turning on auto-newline automatically enables electric indentation. + +When the auto-newline feature is enabled (indicated by \"/la\" on the +modeline after the mode name) newlines are automatically inserted +after special characters such as brace, comma, semi-colon, and colon." (interactive "P") - (setq c-auto-newline (c-calculate-state arg c-auto-newline)) + (setq c-auto-newline + (c-calculate-state arg (and c-auto-newline c-electric-flag))) + (if c-auto-newline (setq c-electric-flag t)) (c-update-modeline) (c-keep-region-active)) +(defalias 'c-toggle-auto-state 'c-toggle-auto-newline) +(make-obsolete 'c-toggle-auto-state 'c-toggle-auto-newline) + (defun c-toggle-hungry-state (&optional arg) "Toggle hungry-delete-key feature. Optional numeric ARG, if supplied, turns on hungry-delete when positive, turns it off when negative, and just toggles it when zero or left out. -When the hungry-delete-key feature is enabled (as evidenced by the -`/h' or `/ah' on the modeline after the mode name) the delete key -gobbles all preceding whitespace in one fell swoop." +When the hungry-delete-key feature is enabled (indicated by \"/h\" on +the modeline after the mode name) the delete key gobbles all preceding +whitespace in one fell swoop." (interactive "P") (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key)) (c-update-modeline) @@ -297,27 +332,38 @@ hungry-delete when positive, turns them off when negative, and just toggles them when zero or left out. -See `c-toggle-auto-state' and `c-toggle-hungry-state' for details." +See `c-toggle-auto-newline' and `c-toggle-hungry-state' for details." (interactive "P") (setq c-auto-newline (c-calculate-state arg c-auto-newline)) (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key)) (c-update-modeline) (c-keep-region-active)) +(defun c-toggle-electric-state (&optional arg) + "Toggle the electric indentation feature. +Optional numeric ARG, if supplied, turns on electric indentation when +positive, turns it off when negative, and just toggles it when zero or +left out." + (interactive "P") + (setq c-electric-flag (c-calculate-state arg c-electric-flag)) + (c-update-modeline) + (c-keep-region-active)) + ;; Electric keys (defun c-electric-backspace (arg) "Delete the preceding character or whitespace. -If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or -\"/ah\" string on the mode line, then all preceding whitespace is -consumed. If however a prefix argument is supplied, or -`c-hungry-delete-key' is nil, or point is inside a literal then the -function in the variable `c-backspace-function' is called." +If `c-hungry-delete-key' is non-nil (indicated by \"/h\" on the mode +line) then all preceding whitespace is consumed. If however a prefix +argument is supplied, or `c-hungry-delete-key' is nil, or point is +inside a literal then the function in the variable +`c-backspace-function' is called." (interactive "*P") - (if (or (not c-hungry-delete-key) - arg - (c-in-literal)) + (if (c-save-buffer-state () + (or (not c-hungry-delete-key) + arg + (c-in-literal))) (funcall c-backspace-function (prefix-numeric-value arg)) (c-hungry-backspace))) @@ -334,15 +380,16 @@ (defun c-electric-delete-forward (arg) "Delete the following character or whitespace. -If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or -\"/ah\" string on the mode line, then all following whitespace is -consumed. If however a prefix argument is supplied, or -`c-hungry-delete-key' is nil, or point is inside a literal then the -function in the variable `c-delete-function' is called." +If `c-hungry-delete-key' is non-nil (indicated by \"/h\" on the mode +line) then all following whitespace is consumed. If however a prefix +argument is supplied, or `c-hungry-delete-key' is nil, or point is +inside a literal then the function in the variable `c-delete-function' +is called." (interactive "*P") - (if (or (not c-hungry-delete-key) - arg - (c-in-literal)) + (if (c-save-buffer-state () + (or (not c-hungry-delete-key) + arg + (c-in-literal))) (funcall c-delete-function (prefix-numeric-value arg)) (c-hungry-delete-forward))) @@ -361,43 +408,54 @@ (defun c-electric-delete (arg) "Deletes preceding or following character or whitespace. This function either deletes forward as `c-electric-delete-forward' or -backward as `c-electric-backspace', depending on the configuration: - -If the function `delete-forward-p' is defined (XEmacs 21) and returns -non-nil, it deletes forward. Else, if the variable -`delete-key-deletes-forward' is defined (XEmacs 20) and is set to -non-nil, it deletes forward. Otherwise it deletes backward. - -Note: This is the way in XEmacs 20 and later to choose the correct -action for the [delete] key, whichever key that means. In other -flavors this function isn't used, instead it's left to the user to -bind [delete] to either \\[c-electric-delete-forward] or \\[c-electric-backspace] as appropriate -\(the keymap `function-key-map' is useful for that). Emacs 21 handles -that automatically, though." +backward as `c-electric-backspace', depending on the configuration: If +the function `delete-forward-p' is defined and returns non-nil, it +deletes forward. Otherwise it deletes backward. + +Note: This is the way in XEmacs to choose the correct action for the +\[delete] key, whichever key that means. Other flavors don't use this +function to control that." (interactive "*P") - (if (or (and (fboundp 'delete-forward-p) ;XEmacs 21 - (delete-forward-p)) - (and (boundp 'delete-key-deletes-forward) ;XEmacs 20 - delete-key-deletes-forward)) + (if (and (fboundp 'delete-forward-p) + (delete-forward-p)) (c-electric-delete-forward arg) (c-electric-backspace arg))) +;; This function is only used in XEmacs. +(defun c-hungry-delete () + "Delete a non-whitespace char, or all whitespace up to the next non-whitespace char. +The direction of deletion depends on the configuration: If the +function `delete-forward-p' is defined and returns non-nil, it deletes +forward using `c-hungry-delete-forward'. Otherwise it deletes +backward using `c-hungry-backspace'. + +Note: This is the way in XEmacs to choose the correct action for the +\[delete] key, whichever key that means. Other flavors don't use this +function to control that." + (interactive) + (if (and (fboundp 'delete-forward-p) + (delete-forward-p)) + (c-hungry-delete-forward) + (c-hungry-backspace))) + (defun c-electric-pound (arg) - "Electric pound (`#') insertion. -Inserts a `#' character specially depending on the variable -`c-electric-pound-behavior'. If a numeric ARG is supplied, or if -point is inside a literal or a macro, nothing special happens." + "Insert a \"#\". +If `c-electric-flag' is set, handle it specially according to the variable +`c-electric-pound-behavior'. If a numeric ARG is supplied, or if point is +inside a literal or a macro, nothing special happens." (interactive "*P") - (if (or arg - (not (memq 'alignleft c-electric-pound-behavior)) - (save-excursion - (skip-chars-backward " \t") - (not (bolp))) - (save-excursion - (and (= (forward-line -1) 0) - (progn (end-of-line) - (eq (char-before) ?\\)))) - (c-in-literal)) + (if (c-save-buffer-state () + (or arg + (not c-electric-flag) + (not (memq 'alignleft c-electric-pound-behavior)) + (save-excursion + (skip-chars-backward " \t") + (not (bolp))) + (save-excursion + (and (= (forward-line -1) 0) + (progn (end-of-line) + (eq (char-before) ?\\)))) + (c-in-literal))) ;; do nothing special (self-insert-command (prefix-numeric-value arg)) ;; place the pound character at the left edge @@ -410,243 +468,332 @@ (goto-char (- (point-max) pos))) ))) +(defun c-point-syntax () + ;; Return the syntactic context of the construct at point. (This is NOT + ;; nec. the same as the s.c. of the line point is on). N.B. This won't work + ;; between the `#' of a cpp thing and what follows (see c-opt-cpp-prefix). + (c-save-buffer-state (;; shut this up too + (c-echo-syntactic-information-p nil) + syntax) + (c-tentative-buffer-changes + ;; insert a newline to isolate the construct at point for syntactic + ;; analysis. + (insert-char ?\n 1) + ;; In AWK (etc.) or in a macro, make sure this CR hasn't changed + ;; the syntax. (There might already be an escaped NL there.) + (when (or (c-at-vsemi-p (1- (point))) + (let ((pt (point))) + (save-excursion + (backward-char) + (and (c-beginning-of-macro) + (progn (c-end-of-macro) + (< (point) pt)))))) + (backward-char) + (insert-char ?\\ 1) + (forward-char)) + (let ((c-syntactic-indentation-in-macros t) + (c-auto-newline-analysis t)) + ;; Turn on syntactic macro analysis to help with auto + ;; newlines only. + (setq syntax (c-guess-basic-syntax)) + nil)) + syntax)) + +(defun c-brace-newlines (syntax) + ;; A brace stands at point. SYNTAX is the syntactic context of this brace + ;; (not necessarily the same as the S.C. of the line it is on). Return + ;; NEWLINES, the list containing some combination of the symbols `before' + ;; and `after' saying where newlines should be inserted. + (c-save-buffer-state + ((syms + ;; This is the list of brace syntactic symbols that can hang. + ;; If any new ones are added to c-offsets-alist, they should be + ;; added here as well. + '(class-open class-close defun-open defun-close + inline-open inline-close + brace-list-open brace-list-close + brace-list-intro brace-entry-open + block-open block-close + substatement-open statement-case-open + extern-lang-open extern-lang-close + namespace-open namespace-close + module-open module-close + composition-open composition-close + inexpr-class-open inexpr-class-close + ;; `statement-cont' is here for the case with a brace + ;; list opener inside a statement. C.f. CASE B.2 in + ;; `c-guess-continued-construct'. + statement-cont)) + ;; shut this up too + (c-echo-syntactic-information-p nil) + symb-newlines) ; e.g. (substatement-open . (after)) + + (setq symb-newlines + ;; Do not try to insert newlines around a special + ;; (Pike-style) brace list. + (if (and c-special-brace-lists + (save-excursion + (c-safe (if (= (char-before) ?{) + (forward-char -1) + (c-forward-sexp -1)) + (c-looking-at-special-brace-list)))) + nil + ;; Seek the matching entry in c-hanging-braces-alist. + (or (c-lookup-lists + syms + ;; Substitute inexpr-class and class-open or + ;; class-close with inexpr-class-open or + ;; inexpr-class-close. + (if (assq 'inexpr-class syntax) + (cond ((assq 'class-open syntax) + '((inexpr-class-open))) + ((assq 'class-close syntax) + '((inexpr-class-close))) + (t syntax)) + syntax) + c-hanging-braces-alist) + '(ignore before after)))) ; Default, when not in c-h-b-l. + + ;; If syntax is a function symbol, then call it using the + ;; defined semantics. + (if (and (not (consp (cdr symb-newlines))) + (functionp (cdr symb-newlines))) + (let ((c-syntactic-context syntax)) + (funcall (cdr symb-newlines) + (car symb-newlines) + (point))) + (cdr symb-newlines)))) + +(defun c-try-one-liner () + ;; Point is just after a newly inserted }. If the non-whitespace + ;; content of the braces is a single line of code, compact the whole + ;; construct to a single line, if this line isn't too long. The Right + ;; Thing is done with comments. + ;; + ;; Point will be left after the }, regardless of whether the clean-up is + ;; done. Return NON-NIL if the clean-up happened, NIL if it didn't. + + (let ((here (point)) + (pos (- (point-max) (point))) + mbeg1 mend1 mbeg4 mend4 + eol-col cmnt-pos cmnt-col cmnt-gap) + + (when + (save-excursion + (save-restriction + ;; Avoid backtracking over a very large block. The one we + ;; deal with here can never be more than three lines. + (narrow-to-region (save-excursion + (forward-line -2) + (point)) + (point)) + (and (c-safe (c-backward-sexp)) + (progn + (forward-char) + (narrow-to-region (point) (1- here)) ; innards of {.} + (looking-at + (cc-eval-when-compile + (concat + "\\(" ; (match-beginning 1) + "[ \t]*\\([\r\n][ \t]*\\)?" ; WS with opt. NL + "\\)" ; (match-end 1) + "[^ \t\r\n]+\\([ \t]+[^ \t\r\n]+\\)*" ; non-WS + "\\(" ; (match-beginning 4) + "[ \t]*\\([\r\n][ \t]*\\)?" ; WS with opt. NL + "\\)\\'"))))))) ; (match-end 4) at EOB. + + (if (c-tentative-buffer-changes + (setq mbeg1 (match-beginning 1) mend1 (match-end 1) + mbeg4 (match-beginning 4) mend4 (match-end 4)) + (backward-char) ; back over the `}' + (save-excursion + (setq cmnt-pos (and (c-backward-single-comment) + (- (point) (- mend1 mbeg1))))) + (delete-region mbeg4 mend4) + (delete-region mbeg1 mend1) + (setq eol-col (save-excursion (end-of-line) (current-column))) + + ;; Necessary to put the closing brace before any line + ;; oriented comment to keep it syntactically significant. + ;; This isn't necessary for block comments, but the result + ;; looks nicer anyway. + (when cmnt-pos + (delete-char 1) ; the `}' has blundered into a comment + (goto-char cmnt-pos) + (setq cmnt-col (1+ (current-column))) + (setq cmnt-pos (1+ cmnt-pos)) ; we're inserting a `}' + (c-skip-ws-backward) + (insert-char ?\} 1) ; reinsert the `}' before the comment. + (setq cmnt-gap (- cmnt-col (current-column))) + (when (zerop cmnt-gap) + (insert-char ?\ 1) ; Put a space before a bare comment. + (setq cmnt-gap 1))) + + (or (null c-max-one-liner-length) + (zerop c-max-one-liner-length) + (<= eol-col c-max-one-liner-length) + ;; Can we trim space before comment to make the line fit? + (and cmnt-gap + (< (- eol-col cmnt-gap) c-max-one-liner-length) + (progn (goto-char cmnt-pos) + (backward-delete-char-untabify + (- eol-col c-max-one-liner-length)) + t)))) + (goto-char (- (point-max) pos)))))) + (defun c-electric-brace (arg) "Insert a brace. -If the auto-newline feature is turned on, as evidenced by the \"/a\" -or \"/ah\" string on the mode line, newlines are inserted before and -after braces based on the value of `c-hanging-braces-alist'. - -Also, the line is re-indented unless a numeric ARG is supplied, the -brace is inserted inside a literal, or `c-syntactic-indentation' is -nil. - -This function does various newline cleanups based on the value of -`c-cleanup-list'." +If `c-electric-flag' is non-nil, the brace is not inside a literal and a +numeric ARG hasn't been supplied, the command performs several electric +actions: + +\(a) If the auto-newline feature is turned on (indicated by \"/ln\" on +the mode line) newlines are inserted before and after the brace as +directed by the settings in `c-hanging-braces-alist'. + +\(b) Any auto-newlines are indented. The original line is also +reindented unless `c-syntactic-indentation' is nil. + +\(c) If auto-newline is turned on, various newline cleanups based on the +settings of `c-cleanup-list' are done." + (interactive "*P") - (let* ((safepos (c-safe-position (point) (c-parse-state))) - (literal (c-in-literal safepos)) - ;; We want to inhibit blinking the paren since this will be - ;; most disruptive. We'll blink it ourselves later on. - (old-blink-paren blink-paren-function) - blink-paren-function) - (cond - ((or literal arg) - (self-insert-command (prefix-numeric-value arg))) - ((not (looking-at "[ \t]*\\\\?$")) - (self-insert-command (prefix-numeric-value arg)) - (if c-syntactic-indentation - (indent-according-to-mode))) - (t - (let* ((syms - ;; This is the list of brace syntactic symbols that can - ;; hang. If any new ones are added to c-offsets-alist, - ;; they should be added here as well. - '(class-open class-close defun-open defun-close - inline-open inline-close - brace-list-open brace-list-close - brace-list-intro brace-entry-open - block-open block-close - substatement-open statement-case-open - extern-lang-open extern-lang-close - namespace-open namespace-close - module-open module-close - composition-open composition-close - inexpr-class-open inexpr-class-close - ;; `statement-cont' is here for the case with a brace - ;; list opener inside a statement. C.f. CASE B.2 in - ;; `c-guess-continued-construct'. - statement-cont)) - (insertion-point (point)) - (preserve-p (and (not (bobp)) - (eq ?\ (char-syntax (char-before))))) - ;; shut this up too - (c-echo-syntactic-information-p nil) - delete-temp-newline syntax newlines) - ;; only insert a newline if there is non-whitespace behind us - (when (save-excursion - (skip-chars-backward " \t") - (not (bolp))) - (c-newline-and-indent) - ;; Set markers around the newline and indention inserted - ;; above. We insert the start marker here and not before - ;; the call to kludge around a misfeature in expand-abbrev: - ;; If the line contains e.g. "else" then expand-abbrev will - ;; be called when c-newline-and-indent inserts the newline. - ;; That function first removes the abbrev "else" and then - ;; inserts the expansion, which is an identical "else" in - ;; this case. So the marker that we put after "else" would - ;; end up before it. - (setq delete-temp-newline - (cons (save-excursion - (end-of-line 0) - (if (eq (char-before) ?\\) - ;; Ignore a line continuation. - (backward-char)) - (skip-chars-backward " \t") - (copy-marker (point) t)) - (point-marker)))) - (unwind-protect - (progn - (if (eq last-command-char ?{) - (setq c-state-cache (cons (point) c-state-cache))) - (self-insert-command (prefix-numeric-value arg)) - (c-save-buffer-state ((c-syntactic-indentation-in-macros t) - (c-auto-newline-analysis t)) - ;; Turn on syntactic macro analysis to help with auto - ;; newlines only. - (setq syntax (c-guess-basic-syntax))) - (setq newlines - (and - c-auto-newline - (or (c-lookup-lists - syms - ;; Substitute inexpr-class and class-open or - ;; class-close with inexpr-class-open or - ;; inexpr-class-close. - (if (assq 'inexpr-class syntax) - (cond ((assq 'class-open syntax) - '((inexpr-class-open))) - ((assq 'class-close syntax) - '((inexpr-class-close))) - (t syntax)) - syntax) - c-hanging-braces-alist) - '(ignore before after)))) - ;; Do not try to insert newlines around a special - ;; (Pike-style) brace list. - (if (and c-special-brace-lists - (save-excursion - (c-save-buffer-state nil - (c-safe (if (= (char-before) ?{) - (forward-char -1) - (c-forward-sexp -1)) - (c-looking-at-special-brace-list))))) - (setq newlines nil)) - ;; If syntax is a function symbol, then call it using the - ;; defined semantics. - (if (and (not (consp (cdr newlines))) - (functionp (cdr newlines))) - (let ((c-syntactic-context syntax)) - (setq newlines - (funcall (cdr newlines) - (car newlines) - insertion-point)))) - ;; does a newline go before the open brace? - (when (memq 'before newlines) - ;; we leave the newline we've put in there before, - ;; but we need to re-indent the line above - (when delete-temp-newline - (set-marker (car delete-temp-newline) nil) - (set-marker (cdr delete-temp-newline) nil) - (setq delete-temp-newline nil)) - (when c-syntactic-indentation - (let ((pos (- (point-max) (point))) - (here (point))) - (forward-line -1) - (indent-according-to-mode) - (goto-char (- (point-max) pos)) - ;; if the buffer has changed due to the - ;; indentation, we need to recalculate syntax for - ;; the current line. - (if (/= (point) here) - (c-save-buffer-state - ((c-syntactic-indentation-in-macros t) - (c-auto-newline-analysis t)) - ;; Turn on syntactic macro analysis to help - ;; with auto newlines only. - (setq syntax (c-guess-basic-syntax)))))))) - ;; must remove the newline we just stuck in (if we really did it) - (when delete-temp-newline - (save-excursion - (delete-region (car delete-temp-newline) - (cdr delete-temp-newline)) - (goto-char (car delete-temp-newline)) - (set-marker (car delete-temp-newline) nil) - (set-marker (cdr delete-temp-newline) nil) - ;; if there is whitespace before point, then preserve - ;; at least one space. - (just-one-space) - (if (not preserve-p) - (delete-char -1))))) - (if (not (memq 'before newlines)) - ;; since we're hanging the brace, we need to recalculate - ;; syntax. - (c-save-buffer-state ((c-syntactic-indentation-in-macros t) - (c-auto-newline-analysis t)) - ;; Turn on syntactic macro analysis to help with auto - ;; newlines only. - (setq syntax (c-guess-basic-syntax)))) - (when c-syntactic-indentation - ;; Now adjust the line's indentation. Don't update the state - ;; cache since c-guess-basic-syntax isn't called when - ;; c-syntactic-context is set. - (let* ((c-syntactic-context syntax)) - (indent-according-to-mode))) - ;; Do all appropriate clean ups - (let ((here (point)) - (pos (- (point-max) (point))) - mbeg mend tmp) - ;; clean up empty defun braces - (if (and c-auto-newline - (memq 'empty-defun-braces c-cleanup-list) - (eq last-command-char ?\}) - (c-intersect-lists '(defun-close class-close inline-close) - syntax) - (progn - (forward-char -1) - (c-skip-ws-backward) - (eq (char-before) ?\{)) - ;; make sure matching open brace isn't in a comment - (not (c-in-literal))) - (delete-region (point) (1- here))) - ;; clean up brace-else-brace and brace-elseif-brace - (when (and c-auto-newline - (eq last-command-char ?\{)) - (cond - ((and (memq 'brace-else-brace c-cleanup-list) - (re-search-backward - (concat "}" - "\\([ \t\n]\\|\\\\\n\\)*" - "else" - "\\([ \t\n]\\|\\\\\n\\)*" - "{") - nil t) - (progn - (setq mbeg (match-beginning 0) - mend (match-end 0)) - (eq (match-end 0) here))) - (delete-region mbeg mend) - (insert-and-inherit "} else {")) - ((and (memq 'brace-elseif-brace c-cleanup-list) - (progn - (goto-char (1- here)) - (setq mend (point)) - (c-skip-ws-backward) - (setq mbeg (point)) - (eq (char-before) ?\))) - (zerop (c-save-buffer-state nil (c-backward-token-2 1 t))) - (eq (char-after) ?\() - (progn - (setq tmp (point)) - (re-search-backward - (concat "}" - "\\([ \t\n]\\|\\\\\n\\)*" - "else" - "\\([ \t\n]\\|\\\\\n\\)+" - "if" - "\\([ \t\n]\\|\\\\\n\\)*") - nil t)) - (eq (match-end 0) tmp)) - (delete-region mbeg mend) - (goto-char mbeg) - (insert ?\ )))) - (goto-char (- (point-max) pos)) - ) - ;; does a newline go after the brace? - (if (memq 'after newlines) - (c-newline-and-indent)) - ))) + (let (safepos literal + ;; We want to inhibit blinking the paren since this would be + ;; most disruptive. We'll blink it ourselves later on. + (old-blink-paren blink-paren-function) + blink-paren-function) + + (c-save-buffer-state () + (setq safepos (c-safe-position (point) (c-parse-state)) + literal (c-in-literal safepos))) + + ;; Insert the brace. Note that expand-abbrev might reindent + ;; the line here if there's a preceding "else" or something. + (self-insert-command (prefix-numeric-value arg)) + + (when (and c-electric-flag (not literal) (not arg)) + (if (not (looking-at "[ \t]*\\\\?$")) + (if c-syntactic-indentation + (indent-according-to-mode)) + + (let ( ;; shut this up too + (c-echo-syntactic-information-p nil) + newlines + ln-syntax br-syntax syntax) ; Syntactic context of the original line, + ; of the brace itself, of the line the brace ends up on. + (c-save-buffer-state ((c-syntactic-indentation-in-macros t) + (c-auto-newline-analysis t)) + (setq ln-syntax (c-guess-basic-syntax))) + (if c-syntactic-indentation + (c-indent-line ln-syntax)) + + (when c-auto-newline + (backward-char) + (setq br-syntax (c-point-syntax) + newlines (c-brace-newlines br-syntax)) + + ;; Insert the BEFORE newline, if wanted, and reindent the newline. + (if (and (memq 'before newlines) + (> (current-column) (current-indentation))) + (if c-syntactic-indentation + ;; Only a plain newline for now - it's indented + ;; after the cleanups when the line has its final + ;; appearance. + (newline) + (c-newline-and-indent))) + (forward-char) + + ;; `syntax' is the syntactic context of the line which ends up + ;; with the brace on it. + (setq syntax (if (memq 'before newlines) br-syntax ln-syntax)) + + ;; Do all appropriate clean ups + (let ((here (point)) + (pos (- (point-max) (point))) + mbeg mend + ) + + ;; `}': clean up empty defun braces + (when (c-save-buffer-state () + (and (memq 'empty-defun-braces c-cleanup-list) + (eq last-command-char ?\}) + (c-intersect-lists '(defun-close class-close inline-close) + syntax) + (progn + (forward-char -1) + (c-skip-ws-backward) + (eq (char-before) ?\{)) + ;; make sure matching open brace isn't in a comment + (not (c-in-literal)))) + (delete-region (point) (1- here)) + (setq here (- (point-max) pos))) + (goto-char here) + + ;; `}': compact to a one-liner defun? + (save-match-data + (when + (and (eq last-command-char ?\}) + (memq 'one-liner-defun c-cleanup-list) + (c-intersect-lists '(defun-close) syntax) + (c-try-one-liner)) + (setq here (- (point-max) pos)))) + + ;; `{': clean up brace-else-brace and brace-elseif-brace + (when (eq last-command-char ?\{) + (cond + ((and (memq 'brace-else-brace c-cleanup-list) + (re-search-backward + (concat "}" + "\\([ \t\n]\\|\\\\\n\\)*" + "else" + "\\([ \t\n]\\|\\\\\n\\)*" + "{" + "\\=") + nil t)) + (delete-region mbeg mend) + (insert-and-inherit "} else {")) + ((and (memq 'brace-elseif-brace c-cleanup-list) + (progn + (goto-char (1- here)) + (setq mend (point)) + (c-skip-ws-backward) + (setq mbeg (point)) + (eq (char-before) ?\))) + (zerop (c-save-buffer-state nil (c-backward-token-2 1 t))) + (eq (char-after) ?\() + ; (progn + ; (setq tmp (point)) + (re-search-backward + (concat "}" + "\\([ \t\n]\\|\\\\\n\\)*" + "else" + "\\([ \t\n]\\|\\\\\n\\)+" + "if" + "\\([ \t\n]\\|\\\\\n\\)*" + "\\=") + nil t);) + ;(eq (match-end 0) tmp); + ) + (delete-region mbeg mend) + (goto-char mbeg) + (insert ?\ )))) + + (goto-char (- (point-max) pos)) + + ;; Indent the line after the cleanups since it might + ;; very well indent differently due to them, e.g. if + ;; c-indent-one-line-block is used together with the + ;; one-liner-defun cleanup. + (when c-syntactic-indentation + (c-indent-line))) + + ;; does a newline go after the brace? + (if (memq 'after newlines) + (c-newline-and-indent)) + )))) + ;; blink the paren (and (eq last-command-char ?\}) (not executing-kbd-macro) @@ -659,332 +806,465 @@ (defun c-electric-slash (arg) "Insert a slash character. +If the slash is inserted immediately after the comment prefix in a c-style +comment, the comment might get closed by removing whitespace and possibly +inserting a \"*\". See the variable `c-cleanup-list'. + Indent the line as a comment, if: - 1. The slash is second of a `//' line oriented comment introducing + 1. The slash is second of a \"//\" line oriented comment introducing token and we are on a comment-only-line, or - 2. The slash is part of a `*/' token that closes a block oriented + 2. The slash is part of a \"*/\" token that closes a block oriented comment. If a numeric ARG is supplied, point is inside a literal, or -`c-syntactic-indentation' is nil, indentation is inhibited." +`c-syntactic-indentation' is nil or `c-electric-flag' is nil, indentation +is inhibited." (interactive "*P") - (let* ((ch (char-before)) - (literal (c-in-literal)) - (indentp (and c-syntactic-indentation - (not arg) + (let ((literal (c-save-buffer-state () (c-in-literal))) + indentp + ;; shut this up + (c-echo-syntactic-information-p nil)) + + ;; comment-close-slash cleanup? This DOESN'T need `c-electric-flag' or + ;; `c-syntactic-indentation' set. + (when (and (not arg) + (eq literal 'c) + (memq 'comment-close-slash c-cleanup-list) + (eq last-command-char ?/) + ; (eq c-block-comment-ender "*/") ; C-style comments ALWAYS end in */ + (save-excursion + (back-to-indentation) + (looking-at (concat c-current-comment-prefix "[ \t]*$")))) + (end-of-line) + (delete-horizontal-space) + (or (eq (char-before) ?*) (insert-char ?* 1))) ; Do I need a t (retain sticky properties) here? + + (setq indentp (and (not arg) + c-syntactic-indentation + c-electric-flag (eq last-command-char ?/) - (or (and (eq ch ?/) - (not literal)) - (and (eq ch ?*) - literal)) - )) - ;; shut this up - (c-echo-syntactic-information-p nil)) + (eq (char-before) (if literal ?* ?/)))) (self-insert-command (prefix-numeric-value arg)) (if indentp (indent-according-to-mode)))) (defun c-electric-star (arg) "Insert a star character. -If the star is the second character of a C style comment introducing -construct, and we are on a comment-only-line, indent line as comment. -If a numeric ARG is supplied, point is inside a literal, or -`c-syntactic-indentation' is nil, indentation is inhibited." +If `c-electric-flag' and `c-syntactic-indentation' are both non-nil, and +the star is the second character of a C style comment starter on a +comment-only-line, indent the line as a comment. If a numeric ARG is +supplied, point is inside a literal, or `c-syntactic-indentation' is nil, +this indentation is inhibited." + (interactive "*P") (self-insert-command (prefix-numeric-value arg)) - ;; if we are in a literal, or if arg is given do not re-indent the + ;; if we are in a literal, or if arg is given do not reindent the ;; current line, unless this star introduces a comment-only line. - (if (and c-syntactic-indentation - (not arg) - (eq (c-in-literal) 'c) - (eq (char-before) ?*) - (save-excursion - (forward-char -1) - (skip-chars-backward "*") - (if (eq (char-before) ?/) - (forward-char -1)) - (skip-chars-backward " \t") - (bolp))) + (if (c-save-buffer-state () + (and c-syntactic-indentation + c-electric-flag + (not arg) + (eq (c-in-literal) 'c) + (eq (char-before) ?*) + (save-excursion + (forward-char -1) + (skip-chars-backward "*") + (if (eq (char-before) ?/) + (forward-char -1)) + (skip-chars-backward " \t") + (bolp)))) (let (c-echo-syntactic-information-p) ; shut this up (indent-according-to-mode)) )) (defun c-electric-semi&comma (arg) "Insert a comma or semicolon. -When the auto-newline feature is turned on, as evidenced by the \"/a\" -or \"/ah\" string on the mode line, a newline might be inserted. See -the variable `c-hanging-semi&comma-criteria' for how newline insertion -is determined. - -When a semicolon is inserted, the line is re-indented unless a numeric -arg is supplied, point is inside a literal, or -`c-syntactic-indentation' is nil. - -Based on the value of `c-cleanup-list', this function cleans up commas -following brace lists and semicolons following defuns." + +If `c-electric-flag' is non-nil, point isn't inside a literal and a +numeric ARG hasn't been supplied, the command performs several electric +actions: + +\(a) When the auto-newline feature is turned on (indicated by \"/ln\" on +the mode line) a newline might be inserted. See the variable +`c-hanging-semi&comma-criteria' for how newline insertion is determined. + +\(b) Any auto-newlines are indented. The original line is also +reindented unless `c-syntactic-indentation' is nil. + +\(c) If auto-newline is turned on, a comma following a brace list or a +semicolon following a defun might be cleaned up, depending on the +settings of `c-cleanup-list'." (interactive "*P") - (let* ((lim (c-most-enclosing-brace (c-parse-state))) - (literal (c-in-literal lim)) + (let* (lim literal c-syntactic-context (here (point)) ;; shut this up (c-echo-syntactic-information-p nil)) - (if (or literal arg) - (self-insert-command (prefix-numeric-value arg)) - ;; do some special stuff with the character - (self-insert-command (prefix-numeric-value arg)) - ;; do all cleanups and newline insertions if c-auto-newline is - ;; turned on - (if (or (not c-auto-newline) - (not (looking-at "[ \t]*\\\\?$"))) - (if c-syntactic-indentation - (indent-according-to-mode)) - ;; clean ups - (let ((pos (- (point-max) (point)))) - (if (and (or (and - (eq last-command-char ?,) - (memq 'list-close-comma c-cleanup-list)) - (and - (eq last-command-char ?\;) - (memq 'defun-close-semi c-cleanup-list))) - (progn - (forward-char -1) - (c-skip-ws-backward) - (eq (char-before) ?})) - ;; make sure matching open brace isn't in a comment - (not (c-in-literal lim))) - (delete-region (point) here)) - (goto-char (- (point-max) pos))) - ;; re-indent line - (if c-syntactic-indentation - (indent-according-to-mode)) - ;; check to see if a newline should be added - (let ((criteria c-hanging-semi&comma-criteria) - answer add-newline-p) - (while criteria - (setq answer (funcall (car criteria))) - ;; only nil value means continue checking - (if (not answer) - (setq criteria (cdr criteria)) - (setq criteria nil) - ;; only 'stop specifically says do not add a newline - (setq add-newline-p (not (eq answer 'stop))) - )) - (if add-newline-p - (c-newline-and-indent)) - ))))) + + (c-save-buffer-state () + (setq lim (c-most-enclosing-brace (c-parse-state)) + literal (c-in-literal lim))) + + (self-insert-command (prefix-numeric-value arg)) + + (if (and c-electric-flag (not literal) (not arg)) + ;; do all cleanups and newline insertions if c-auto-newline is on. + (if (or (not c-auto-newline) + (not (looking-at "[ \t]*\\\\?$"))) + (if c-syntactic-indentation + (c-indent-line)) + ;; clean ups: list-close-comma or defun-close-semi + (let ((pos (- (point-max) (point)))) + (if (c-save-buffer-state () + (and (or (and + (eq last-command-char ?,) + (memq 'list-close-comma c-cleanup-list)) + (and + (eq last-command-char ?\;) + (memq 'defun-close-semi c-cleanup-list))) + (progn + (forward-char -1) + (c-skip-ws-backward) + (eq (char-before) ?})) + ;; make sure matching open brace isn't in a comment + (not (c-in-literal lim)))) + (delete-region (point) here)) + (goto-char (- (point-max) pos))) + ;; reindent line + (when c-syntactic-indentation + (setq c-syntactic-context (c-guess-basic-syntax)) + (c-indent-line c-syntactic-context)) + ;; check to see if a newline should be added + (let ((criteria c-hanging-semi&comma-criteria) + answer add-newline-p) + (while criteria + (setq answer (funcall (car criteria))) + ;; only nil value means continue checking + (if (not answer) + (setq criteria (cdr criteria)) + (setq criteria nil) + ;; only 'stop specifically says do not add a newline + (setq add-newline-p (not (eq answer 'stop))) + )) + (if add-newline-p + (c-newline-and-indent)) + ))))) (defun c-electric-colon (arg) "Insert a colon. -If the auto-newline feature is turned on, as evidenced by the \"/a\" -or \"/ah\" string on the mode line, newlines are inserted before and -after colons based on the value of `c-hanging-colons-alist'. - -Also, the line is re-indented unless a numeric ARG is supplied, the -colon is inserted inside a literal, or `c-syntactic-indentation' is -nil. - -This function cleans up double colon scope operators based on the -value of `c-cleanup-list'." +If `c-electric-flag' is non-nil, the colon is not inside a literal and a +numeric ARG hasn't been supplied, the command performs several electric +actions: + +\(a) If the auto-newline feature is turned on (indicated by \"/ln\" on +the mode line) newlines are inserted before and after the colon based on +the settings in `c-hanging-colons-alist'. + +\(b) Any auto-newlines are indented. The original line is also +reindented unless `c-syntactic-indentation' is nil. + +\(c) If auto-newline is turned on, whitespace between two colons will be +\"cleaned up\" leaving a scope operator, if this action is set in +`c-cleanup-list'." + (interactive "*P") (let* ((bod (c-point 'bod)) - (literal (c-in-literal bod)) + (literal (c-save-buffer-state () (c-in-literal bod))) newlines is-scope-op ;; shut this up (c-echo-syntactic-information-p nil)) - (cond - ((or literal arg) - (self-insert-command (prefix-numeric-value arg))) - ((not (looking-at "[ \t]*\\\\?$")) - (self-insert-command (prefix-numeric-value arg)) - (if c-syntactic-indentation - (indent-according-to-mode))) - (t - ;; insert the colon, then do any specified cleanups - (self-insert-command (prefix-numeric-value arg)) - (let ((pos (- (point-max) (point))) - (here (point))) - (if (and c-auto-newline - (memq 'scope-operator c-cleanup-list) - (eq (char-before) ?:) - (progn - (forward-char -1) - (c-skip-ws-backward) - (eq (char-before) ?:)) - (not (c-in-literal)) - (not (eq (char-after (- (point) 2)) ?:))) - (progn - (delete-region (point) (1- here)) - (setq is-scope-op t))) - (goto-char (- (point-max) pos))) - ;; indent the current line if it's done syntactically. - (if c-syntactic-indentation - ;; Cannot use the same syntax analysis as we find below, - ;; since that's made with c-syntactic-indentation-in-macros - ;; always set to t. - (indent-according-to-mode)) - (c-save-buffer-state - ((c-syntactic-indentation-in-macros t) - (c-auto-newline-analysis t) - ;; Turn on syntactic macro analysis to help with auto newlines - ;; only. - (syntax (c-guess-basic-syntax)) - (elem syntax)) - ;; Translate substatement-label to label for this operation. - (while elem - (if (eq (car (car elem)) 'substatement-label) - (setcar (car elem) 'label)) - (setq elem (cdr elem))) - ;; some language elements can only be determined by checking - ;; the following line. Lets first look for ones that can be - ;; found when looking on the line with the colon - (setq newlines - (and c-auto-newline - (or (c-lookup-lists '(case-label label access-label) - syntax c-hanging-colons-alist) - (c-lookup-lists '(member-init-intro inher-intro) - (progn - (insert ?\n) - (unwind-protect - (c-guess-basic-syntax) - (delete-char -1))) - c-hanging-colons-alist))))) - ;; does a newline go before the colon? Watch out for already - ;; non-hung colons. However, we don't unhang them because that - ;; would be a cleanup (and anti-social). - (if (and (memq 'before newlines) - (not is-scope-op) - (save-excursion - (skip-chars-backward ": \t") - (not (bolp)))) - (let ((pos (- (point-max) (point)))) - (forward-char -1) - (c-newline-and-indent) - (goto-char (- (point-max) pos)))) - ;; does a newline go after the colon? - (if (and (memq 'after (cdr-safe newlines)) - (not is-scope-op)) - (c-newline-and-indent)) - )))) + (self-insert-command (prefix-numeric-value arg)) + ;; Any electric action? + (if (and c-electric-flag (not literal) (not arg)) + ;; Unless we're at EOL, only re-indentation happens. + (if (not (looking-at "[ \t]*\\\\?$")) + (if c-syntactic-indentation + (indent-according-to-mode)) + + ;; scope-operator clean-up? + (let ((pos (- (point-max) (point))) + (here (point))) + (if (c-save-buffer-state () ; Why do we need this? [ACM, 2003-03-12] + (and c-auto-newline + (memq 'scope-operator c-cleanup-list) + (eq (char-before) ?:) + (progn + (forward-char -1) + (c-skip-ws-backward) + (eq (char-before) ?:)) + (not (c-in-literal)) + (not (eq (char-after (- (point) 2)) ?:)))) + (progn + (delete-region (point) (1- here)) + (setq is-scope-op t))) + (goto-char (- (point-max) pos))) + + ;; indent the current line if it's done syntactically. + (if c-syntactic-indentation + ;; Cannot use the same syntax analysis as we find below, + ;; since that's made with c-syntactic-indentation-in-macros + ;; always set to t. + (indent-according-to-mode)) + + ;; Calculate where, if anywhere, we want newlines. + (c-save-buffer-state + ((c-syntactic-indentation-in-macros t) + (c-auto-newline-analysis t) + ;; Turn on syntactic macro analysis to help with auto newlines + ;; only. + (syntax (c-guess-basic-syntax)) + (elem syntax)) + ;; Translate substatement-label to label for this operation. + (while elem + (if (eq (car (car elem)) 'substatement-label) + (setcar (car elem) 'label)) + (setq elem (cdr elem))) + ;; some language elements can only be determined by checking + ;; the following line. Lets first look for ones that can be + ;; found when looking on the line with the colon + (setq newlines + (and c-auto-newline + (or (c-lookup-lists '(case-label label access-label) + syntax c-hanging-colons-alist) + (c-lookup-lists '(member-init-intro inher-intro) + (progn + (insert ?\n) + (unwind-protect + (c-guess-basic-syntax) + (delete-char -1))) + c-hanging-colons-alist))))) + ;; does a newline go before the colon? Watch out for already + ;; non-hung colons. However, we don't unhang them because that + ;; would be a cleanup (and anti-social). + (if (and (memq 'before newlines) + (not is-scope-op) + (save-excursion + (skip-chars-backward ": \t") + (not (bolp)))) + (let ((pos (- (point-max) (point)))) + (forward-char -1) + (c-newline-and-indent) + (goto-char (- (point-max) pos)))) + ;; does a newline go after the colon? + (if (and (memq 'after (cdr-safe newlines)) + (not is-scope-op)) + (c-newline-and-indent)) + )))) (defun c-electric-lt-gt (arg) - "Insert a less-than, or greater-than character. -The line will be re-indented if the character inserted is the second -of a C++ style stream operator and the buffer is in C++ mode. -Exceptions are when a numeric argument is supplied, point is inside a -literal, or `c-syntactic-indentation' is nil, in which case the line -will not be re-indented." + "Insert a \"<\" or \">\" character. +If the current language uses angle bracket parens (e.g. template +arguments in C++), try to find out if the inserted character is a +paren and give it paren syntax if appropriate. + +If `c-electric-flag' and `c-syntactic-indentation' are both non-nil, the +line will be reindented if the inserted character is a paren or if it +finishes a C++ style stream operator in C++ mode. Exceptions are when a +numeric argument is supplied, or the point is inside a literal." + (interactive "*P") - (let ((indentp (and c-syntactic-indentation - (not arg) - (eq (char-before) last-command-char) - (not (c-in-literal)))) - ;; shut this up - (c-echo-syntactic-information-p nil)) + (let ((c-echo-syntactic-information-p nil) + final-pos close-paren-inserted) + (self-insert-command (prefix-numeric-value arg)) - (if indentp - (indent-according-to-mode)))) + (setq final-pos (point)) + + (c-save-buffer-state (c-parse-and-markup-<>-arglists + c-restricted-<>-arglists + <-pos) + + (when c-recognize-<>-arglists + (if (eq last-command-char ?<) + (when (and (progn + (backward-char) + (= (point) + (progn + (c-beginning-of-current-token) + (point)))) + (progn + (c-backward-token-2) + (looking-at c-opt-<>-sexp-key))) + (c-mark-<-as-paren (1- final-pos))) + + ;; It's a ">". Check if there's an earlier "<" which either has + ;; open paren syntax already or that can be recognized as an arglist + ;; together with this ">". Note that this won't work in cases like + ;; "template " but they ought to be rare. + + (save-restriction + ;; Narrow to avoid that `c-forward-<>-arglist' below searches past + ;; our position. + (narrow-to-region (point-min) final-pos) + + (while (and + (progn + (goto-char final-pos) + (c-syntactic-skip-backward "^<;}" nil t) + (eq (char-before) ?<)) + (progn + (backward-char) + ;; If the "<" already got open paren syntax we know we + ;; have the matching closer. Handle it and exit the + ;; loop. + (if (looking-at "\\s\(") + (progn + (c-mark->-as-paren (1- final-pos)) + (setq close-paren-inserted t) + nil) + t)) + + (progn + (setq <-pos (point)) + (c-backward-syntactic-ws) + (c-simple-skip-symbol-backward)) + (or (looking-at c-opt-<>-sexp-key) + (not (looking-at c-keywords-regexp))) + + (let ((c-parse-and-markup-<>-arglists t) + c-restricted-<>-arglists + (containing-sexp + (c-most-enclosing-brace (c-parse-state)))) + (when (and containing-sexp + (progn (goto-char containing-sexp) + (eq (char-after) ?\()) + (not (eq (get-text-property (point) 'c-type) + 'c-decl-arg-start))) + (setq c-restricted-<>-arglists t)) + (goto-char <-pos) + (c-forward-<>-arglist nil)) + + ;; Loop here if the "<" we found above belongs to a nested + ;; angle bracket sexp. When we start over we'll find the + ;; previous or surrounding sexp. + (if (< (point) final-pos) + t + (setq close-paren-inserted t) + nil))))))) + (goto-char final-pos) + + ;; Indent the line if appropriate. + (when (and c-electric-flag c-syntactic-indentation) + (backward-char) + (when (prog1 (or (looking-at "\\s\(\\|\\s\)") + (and (c-major-mode-is 'c++-mode) + (progn + (c-beginning-of-current-token) + (looking-at "<<\\|>>")) + (= (match-end 0) final-pos))) + (goto-char final-pos)) + (indent-according-to-mode))) + + (when (and close-paren-inserted + (not executing-kbd-macro) + blink-paren-function) + ;; Note: Most paren blink functions, such as the standard + ;; `blink-matching-open', currently doesn't handle paren chars + ;; marked with text properties very well. Maybe we should avoid + ;; this call for the time being? + (funcall blink-paren-function)))) (defun c-electric-paren (arg) "Insert a parenthesis. -Some newline cleanups are done if appropriate; see the variable -`c-cleanup-list'. - -Also, the line is re-indented unless a numeric ARG is supplied, the -parenthesis is inserted inside a literal, or `c-syntactic-indentation' -is nil." +If `c-syntactic-indentation' and `c-electric-flag' are both non-nil, the +line is reindented unless a numeric ARG is supplied, or the parenthesis +is inserted inside a literal. + +Whitespace between a function name and the parenthesis may get added or +removed; see the variable `c-cleanup-list'. + +Also, if `c-electric-flag' and `c-auto-newline' are both non-nil, some +newline cleanups are done if appropriate; see the variable `c-cleanup-list'." (interactive "*P") - (let ((literal (c-in-literal (c-point 'bod))) + (let ((literal (c-save-buffer-state () (c-in-literal))) ;; shut this up (c-echo-syntactic-information-p nil)) - (if (or arg literal) - (self-insert-command (prefix-numeric-value arg)) - ;; do some special stuff with the character - (let* (;; We want to inhibit blinking the paren since this will - ;; be most disruptive. We'll blink it ourselves - ;; afterwards. - (old-blink-paren blink-paren-function) - blink-paren-function - (noblink (eq last-input-event ?\())) - (self-insert-command (prefix-numeric-value arg)) - (if c-syntactic-indentation - (indent-according-to-mode)) - (when (looking-at "[ \t]*\\\\?$") - (when c-auto-newline - ;; Do all appropriate clean ups - (let ((here (point)) - (pos (- (point-max) (point))) - mbeg mend) - ;; clean up brace-elseif-brace - (if (and (memq 'brace-elseif-brace c-cleanup-list) - (eq last-command-char ?\() - (re-search-backward - (concat "}" - "\\([ \t\n]\\|\\\\\n\\)*" - "else" - "\\([ \t\n]\\|\\\\\n\\)+" - "if" - "\\([ \t\n]\\|\\\\\n\\)*" - "(") - nil t) - (save-excursion - (setq mbeg (match-beginning 0) - mend (match-end 0)) - (= mend here)) - (not (c-in-literal))) - (progn - (delete-region mbeg mend) - (insert-and-inherit "} else if (")) - ;; clean up brace-catch-brace - (goto-char here) - (if (and (memq 'brace-catch-brace c-cleanup-list) - (eq last-command-char ?\() - (re-search-backward - (concat "}" - "\\([ \t\n]\\|\\\\\n\\)*" - "catch" - "\\([ \t\n]\\|\\\\\n\\)*" - "(") - nil t) - (save-excursion - (setq mbeg (match-beginning 0) - mend (match-end 0)) - (= mend here)) - (not (c-in-literal))) - (progn - (delete-region mbeg mend) - (insert-and-inherit "} catch (")))) - (goto-char (- (point-max) pos)) - ))) - (let (beg (end (1- (point)))) - (cond ((and (memq 'space-before-funcall c-cleanup-list) - (eq last-command-char ?\() - (save-excursion - (backward-char) - (skip-chars-backward " \t") - (setq beg (point)) - (c-on-identifier))) - (save-excursion - (delete-region beg end) - (goto-char beg) - (insert ?\ ))) - ((and (memq 'compact-empty-funcall c-cleanup-list) - (eq last-command-char ?\)) - (save-excursion - (c-safe (backward-char 2)) - (when (looking-at "()") - (setq end (point)) - (skip-chars-backward " \t") - (setq beg (point)) - (c-on-identifier)))) - (delete-region beg end)))) - (and (not executing-kbd-macro) - old-blink-paren - (not noblink) - (funcall old-blink-paren)))))) + (self-insert-command (prefix-numeric-value arg)) + + (if (and (not arg) (not literal)) + (let* ( ;; We want to inhibit blinking the paren since this will + ;; be most disruptive. We'll blink it ourselves + ;; afterwards. + (old-blink-paren blink-paren-function) + blink-paren-function) + (if (and c-syntactic-indentation c-electric-flag) + (indent-according-to-mode)) + + ;; If we're at EOL, check for new-line clean-ups. + (when (and c-electric-flag c-auto-newline + (looking-at "[ \t]*\\\\?$")) + + ;; clean up brace-elseif-brace + (when + (and (memq 'brace-elseif-brace c-cleanup-list) + (eq last-command-char ?\() + (re-search-backward + (concat "}" + "\\([ \t\n]\\|\\\\\n\\)*" + "else" + "\\([ \t\n]\\|\\\\\n\\)+" + "if" + "\\([ \t\n]\\|\\\\\n\\)*" + "(" + "\\=") + nil t) + (not (c-save-buffer-state () (c-in-literal)))) + (delete-region (match-beginning 0) (match-end 0)) + (insert-and-inherit "} else if (")) + + ;; clean up brace-catch-brace + (when + (and (memq 'brace-catch-brace c-cleanup-list) + (eq last-command-char ?\() + (re-search-backward + (concat "}" + "\\([ \t\n]\\|\\\\\n\\)*" + "catch" + "\\([ \t\n]\\|\\\\\n\\)*" + "(" + "\\=") + nil t) + (not (c-save-buffer-state () (c-in-literal)))) + (delete-region (match-beginning 0) (match-end 0)) + (insert-and-inherit "} catch ("))) + + ;; Check for clean-ups at function calls. These two DON'T need + ;; `c-electric-flag' or `c-syntactic-indentation' set. + ;; Point is currently just after the inserted paren. + (let (beg (end (1- (point)))) + (cond + + ;; space-before-funcall clean-up? + ((and (memq 'space-before-funcall c-cleanup-list) + (eq last-command-char ?\() + (save-excursion + (backward-char) + (skip-chars-backward " \t") + (setq beg (point)) + (c-save-buffer-state () (c-on-identifier)))) + (save-excursion + (delete-region beg end) + (goto-char beg) + (insert ?\ ))) + + ;; compact-empty-funcall clean-up? + ((c-save-buffer-state () + (and (memq 'compact-empty-funcall c-cleanup-list) + (eq last-command-char ?\)) + (save-excursion + (c-safe (backward-char 2)) + (when (looking-at "()") + (setq end (point)) + (skip-chars-backward " \t") + (setq beg (point)) + (c-on-identifier))))) + (delete-region beg end)))) + (and (eq last-input-event ?\)) + (not executing-kbd-macro) + old-blink-paren + (funcall old-blink-paren)))))) (defun c-electric-continued-statement () "Reindent the current line if appropriate. @@ -995,16 +1275,18 @@ The line is reindented if there is nothing but whitespace before the keyword on the line, the keyword is not inserted inside a literal, and -`c-syntactic-indentation' is non-nil." +`c-electric-flag' and `c-syntactic-indentation' are both non-nil." (let (;; shut this up (c-echo-syntactic-information-p nil)) - (when (and c-syntactic-indentation - (not (eq last-command-char ?_)) - (= (save-excursion - (skip-syntax-backward "w") - (point)) - (c-point 'boi)) - (not (c-in-literal (c-point 'bod)))) + (when (c-save-buffer-state () + (and c-electric-flag + c-syntactic-indentation + (not (eq last-command-char ?_)) + (= (save-excursion + (skip-syntax-backward "w") + (point)) + (c-point 'boi)) + (not (c-in-literal (c-point 'bod))))) ;; Have to temporarily insert a space so that ;; c-guess-basic-syntax recognizes the keyword. Follow the ;; space with a nonspace to avoid messing up any whitespace @@ -1016,36 +1298,19 @@ (delete-char -2))))) -;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus -;; originally contributed by Terry_Glanfield.Southern@rxuk.xerox.com (defun c-forward-into-nomenclature (&optional arg) - "Move forward to end of a nomenclature section or word. -With arg, do it arg times." + "Compatibility alias for `c-forward-subword'." (interactive "p") - (let ((case-fold-search nil)) - (if (> arg 0) - (re-search-forward - (cc-eval-when-compile - (concat "\\W*\\([" c-upper "]*[" c-lower c-digit "]*\\)")) - (point-max) t arg) - (while (and (< arg 0) - (re-search-backward - (cc-eval-when-compile - (concat - "\\(\\(\\W\\|[" c-lower c-digit "]\\)[" c-upper "]+" - "\\|\\W\\w+\\)")) - (point-min) 0)) - (forward-char 1) - (setq arg (1+ arg))))) - (c-keep-region-active)) + (require 'cc-subword) + (c-forward-subword arg)) +(make-obsolete 'c-forward-into-nomenclature 'c-forward-subword) (defun c-backward-into-nomenclature (&optional arg) - "Move backward to beginning of a nomenclature section or word. -With optional ARG, move that many times. If ARG is negative, move -forward." + "Compatibility alias for `c-backward-subword'." (interactive "p") - (c-forward-into-nomenclature (- arg)) - (c-keep-region-active)) + (require 'cc-subword) + (c-backward-subword arg)) +(make-obsolete 'c-backward-into-nomenclature 'c-backward-subword) (defun c-scope-operator () "Insert a double colon scope operator at point. @@ -1246,6 +1511,8 @@ ;; following one is chosen instead (if there is any). The end ;; position is at the next line, providing there is one before the ;; declaration. + ;; + ;; This function might do hidden buffer changes. (save-excursion ;; Note: Some code duplication in `c-beginning-of-defun' and @@ -1369,6 +1636,604 @@ (push-mark (cdr decl-limits) nil t)))) +(defun c-in-comment-line-prefix-p () + ;; Point is within a comment. Is it also within a comment-prefix? + ;; Space at BOL which precedes a comment-prefix counts as part of it. + ;; + ;; This function might do hidden buffer changes. + (let ((here (point))) + (save-excursion + (beginning-of-line) + (skip-chars-forward " \t") + (and (looking-at c-current-comment-prefix) + (/= (match-beginning 0) (match-end 0)) + (< here (match-end 0)))))) + +(defun c-narrow-to-comment-innards (range) + ;; Narrow to the "inside" of the comment (block) defined by range, as + ;; follows: + ;; + ;; A c-style block comment has its opening "/*" and its closing "*/" (if + ;; present) removed. A c++-style line comment retains its opening "//" but + ;; has any final NL removed. If POINT is currently outwith these innards, + ;; move it to the appropriate boundary. + ;; + ;; This narrowing simplifies the sentence movement functions, since it + ;; eliminates awkward things at the boundaries of the comment (block). + ;; + ;; This function might do hidden buffer changes. + (let* ((lit-type (c-literal-type range)) + (beg (if (eq lit-type 'c) (+ (car range) 2) (car range))) + (end (if (eq lit-type 'c) + (if (and (eq (char-before (cdr range)) ?/) + (eq (char-before (1- (cdr range))) ?*)) + (- (cdr range) 2) + (point-max)) + (if (eq (cdr range) (point-max)) + (point-max) + (- (cdr range) 1))))) + (if (> (point) end) + (goto-char end)) ; This would be done automatically by ... + (if (< (point) beg) + (goto-char beg)) ; ... narrow-to-region but is not documented. + (narrow-to-region beg end))) + +(defun c-beginning-of-sentence-in-comment (range) + ;; Move backwards to the "beginning of a sentence" within the comment + ;; defined by RANGE, a cons of its starting and ending positions. If we + ;; find a BOS, return NIL. Otherwise, move point to just before the start + ;; of the comment and return T. + ;; + ;; The BOS is either text which follows a regexp match of sentence-end, + ;; or text which is a beginning of "paragraph". + ;; Comment-prefixes are treated like WS when calculating BOSes or BOPs. + ;; + ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el. + ;; It is not a general function, but is intended only for calling from + ;; c-move-over-sentence. Not all preconditions have been explicitly stated. + ;; + ;; This function might do hidden buffer changes. + (save-match-data + (let ((start-point (point))) + (save-restriction + (c-narrow-to-comment-innards range) ; This may move point back. + (let* ((here (point)) + last + (here-filler ; matches WS and comment-prefices at point. + (concat "\\=\\(^[ \t]*\\(" c-current-comment-prefix "\\)" + "\\|[ \t\n\r\f]\\)*")) + (prefix-at-bol-here ; matches WS and prefix at BOL, just before point + (concat "^[ \t]*\\(" c-current-comment-prefix "\\)[ \t\n\r\f]*\\=")) + ;; First, find the previous paragraph start, if any. + (par-beg ; point where non-WS/non-prefix text of paragraph starts. + (save-excursion + (forward-paragraph -1) ; uses cc-mode values of + ; paragraph-\(start\|separate\) + (if (> (re-search-forward here-filler nil t) here) + (goto-char here)) + (when (>= (point) here) + (forward-paragraph -2) + (if (> (re-search-forward here-filler nil t) here) + (goto-char here))) + (point)))) + + ;; Now seek successively earlier sentence ends between PAR-BEG and + ;; HERE, until the "start of sentence" following it is earlier than + ;; HERE, or we hit PAR-BEG. Beware of comment prefices! + (while (and (re-search-backward (c-sentence-end) par-beg 'limit) + (setq last (point)) + (goto-char (match-end 0)) ; tentative beginning of sentence + (or (>= (point) here) + (and (not (bolp)) ; Found a non-blank comment-prefix? + (save-excursion + (if (re-search-backward prefix-at-bol-here nil t) + (/= (match-beginning 1) (match-end 1))))) + (progn ; Skip the crud to find a real b-o-s. + (if (c-in-comment-line-prefix-p) + (beginning-of-line)) + (re-search-forward here-filler) ; always succeeds. + (>= (point) here)))) + (goto-char last)) + (re-search-forward here-filler))) + + (if (< (point) start-point) + nil + (goto-char (car range)) + t)))) + +(defun c-end-of-sentence-in-comment (range) + ;; Move forward to the "end of a sentence" within the comment defined by + ;; RANGE, a cons of its starting and ending positions (enclosing the opening + ;; comment delimiter and the terminating */ or newline). If we find an EOS, + ;; return NIL. Otherwise, move point to just after the end of the comment + ;; and return T. + ;; + ;; The EOS is just after the non-WS part of the next match of the regexp + ;; sentence-end. Typically, this is just after one of [.!?]. If there is + ;; no sentence-end match following point, any WS before the end of the + ;; comment will count as EOS, providing we're not already in it. + ;; + ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el. + ;; It is not a general function, but is intended only for calling from + ;; c-move-over-sentence. + ;; + ;; This function might do hidden buffer changes. + (save-match-data + (let ((start-point (point)) + ;; (lit-type (c-literal-type range)) ; Commented out, 2005/11/23, ACM + ) + (save-restriction + (c-narrow-to-comment-innards range) ; This might move point forwards. + (let* ((here (point)) + (par-end ; EOL position of last text in current/next paragraph. + (save-excursion + ;; The cc-mode values of paragraph-\(start\|separate\), set + ;; in c-setup-paragraph-variables, are used in the + ;; following. + (forward-paragraph 1) + (if (eq (preceding-char) ?\n) (forward-char -1)) + (when (<= (point) here) ; can happen, e.g., when HERE is at EOL. + (goto-char here) + (forward-paragraph 2) + (if (eq (preceding-char) ?\n) (forward-char -1))) + (point))) + + last + (prefix-at-bol-here + (concat "^[ \t]*\\(" c-current-comment-prefix "\\)\\="))) + ;; Go forward one "comment-prefix which looks like sentence-end" + ;; each time round the following: + (while (and (re-search-forward (c-sentence-end) par-end 'limit) + (progn + (setq last (point)) + (skip-chars-backward " \t\n") + (or (and (not (bolp)) + (re-search-backward prefix-at-bol-here nil t) + (/= (match-beginning 1) (match-end 1))) + (<= (point) here)))) + (goto-char last)) + + ;; Take special action if we're up against the end of a comment (of + ;; either sort): Leave point just after the last non-ws text. + (if (eq (point) (point-max)) + (while (or (/= (skip-chars-backward " \t\n") 0) + (and (re-search-backward prefix-at-bol-here nil t) + (/= (match-beginning 1) (match-end 1)))))))) + + (if (> (point) start-point) + nil + (goto-char (cdr range)) + t)))) + +(defun c-beginning-of-sentence-in-string (range) + ;; Move backwards to the "beginning of a sentence" within the string defined + ;; by RANGE, a cons of its starting and ending positions (enclosing the + ;; string quotes). If we find a BOS, return NIL. Otherwise, move point to + ;; just before the start of the string and return T. + ;; + ;; The BOS is either the text which follows a regexp match of sentence-end + ;; or text which is a beginning of "paragraph". For the purposes of + ;; determining paragraph boundaries, escaped newlines are treated as + ;; ordinary newlines. + ;; + ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el. + ;; It is not a general function, but is intended only for calling from + ;; c-move-over-sentence. + ;; + ;; This function might do hidden buffer changes. + (save-match-data + (let* ((here (point)) last + (end (1- (cdr range))) + (here-filler ; matches WS and escaped newlines at point. + "\\=\\([ \t\n\r\f]\\|\\\\[\n\r]\\)*") + ;; Enhance paragraph-start and paragraph-separate also to recognise + ;; blank lines terminated by escaped EOLs. IT MAY WELL BE that + ;; these values should be customizable user options, or something. + (paragraph-start c-string-par-start) + (paragraph-separate c-string-par-separate) + + (par-beg ; beginning of current (or previous) paragraph. + (save-excursion + (save-restriction + (narrow-to-region (1+ (car range)) end) + (forward-paragraph -1) ; uses above values of + ; paragraph-\(start\|separate\) + (if (> (re-search-forward here-filler nil t) here) + (goto-char here)) + (when (>= (point) here) + (forward-paragraph -2) + (if (> (re-search-forward here-filler nil t) here) + (goto-char here))) + (point))))) + ;; Now see if we can find a sentence end after PAR-BEG. + (while (and (re-search-backward c-sentence-end-with-esc-eol par-beg 'limit) + (setq last (point)) + (goto-char (match-end 0)) + (or (> (point) end) + (progn + (re-search-forward + here-filler end t) ; always succeeds. Use end rather + ; than here, in case point starts + ; beyond the closing quote. + (>= (point) here)))) + (goto-char last)) + (re-search-forward here-filler here t) + (if (< (point) here) + nil + (goto-char (car range)) + t)))) + +(defun c-end-of-sentence-in-string (range) + ;; Move forward to the "end of a sentence" within the string defined by + ;; RANGE, a cons of its starting and ending positions. If we find an EOS, + ;; return NIL. Otherwise, move point to just after the end of the string + ;; and return T. + ;; + ;; The EOS is just after the non-WS part of the next match of the regexp + ;; sentence-end. Typically, this is just after one of [.!?]. If there is + ;; no sentence-end match following point, any WS before the end of the + ;; string will count as EOS, providing we're not already in it. + ;; + ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el. + ;; It is not a general function, but is intended only for calling from + ;; c-move-over-sentence. + ;; + ;; This function might do hidden buffer changes. + (save-match-data + (let* ((here (point)) + last + ;; Enhance paragraph-start and paragraph-separate to recognise + ;; blank lines terminated by escaped EOLs. + (paragraph-start c-string-par-start) + (paragraph-separate c-string-par-separate) + + (par-end ; EOL position of last text in current/next paragraph. + (save-excursion + (save-restriction + (narrow-to-region (car range) (1- (cdr range))) + ;; The above values of paragraph-\(start\|separate\) are used + ;; in the following. + (forward-paragraph 1) + (setq last (point)) + ;; (re-search-backward filler-here nil t) would find an empty + ;; string. Therefore we simulate it by the following: + (while (or (/= (skip-chars-backward " \t\n\r\f") 0) + (re-search-backward "\\\\\\($\\)\\=" nil t))) + (unless (> (point) here) + (goto-char last) + (forward-paragraph 1) + (while (or (/= (skip-chars-backward " \t\n\r\f") 0) + (re-search-backward "\\\\\\($\\)\\=" nil t)))) + (point))))) + ;; Try to go forward a sentence. + (when (re-search-forward c-sentence-end-with-esc-eol par-end 'limit) + (setq last (point)) + (while (or (/= (skip-chars-backward " \t\n") 0) + (re-search-backward "\\\\\\($\\)\\=" nil t)))) + ;; Did we move a sentence, or did we hit the end of the string? + (if (> (point) here) + nil + (goto-char (cdr range)) + t)))) + +(defun c-ascertain-preceding-literal () + ;; Point is not in a literal (i.e. comment or string (include AWK regexp)). + ;; If a literal is the next thing (aside from whitespace) to be found before + ;; point, return a cons of its start.end positions (enclosing the + ;; delimiters). Otherwise return NIL. + ;; + ;; This function might do hidden buffer changes. + (save-excursion + (c-collect-line-comments + (let ((here (point)) + pos) + (if (c-backward-single-comment) + (cons (point) (progn (c-forward-single-comment) (point))) + (save-restriction + ;; to prevent `looking-at' seeing a " at point. + (narrow-to-region (point-min) here) + (when + (or + ;; An EOL can act as an "open string" terminator in AWK. + (looking-at c-ws*-string-limit-regexp) + (and (not (bobp)) + (progn (backward-char) + (looking-at c-string-limit-regexp)))) + (goto-char (match-end 0)) ; just after the string terminator. + (setq pos (point)) + (c-safe (c-backward-sexp 1) ; move back over the string. + (cons (point) pos))))))))) + +(defun c-ascertain-following-literal () + ;; Point is not in a literal (i.e. comment or string (include AWK regexp)). + ;; If a literal is the next thing (aside from whitespace) following point, + ;; return a cons of its start.end positions (enclosing the delimiters). + ;; Otherwise return NIL. + ;; + ;; This function might do hidden buffer changes. + (save-excursion + (c-collect-line-comments + (let (pos) + (c-skip-ws-forward) + (if (looking-at c-string-limit-regexp) ; string-delimiter. + (cons (point) (or (c-safe (progn (c-forward-sexp 1) (point))) + (point-max))) + (setq pos (point)) + (if (c-forward-single-comment) + (cons pos (point)))))))) + +(defun c-after-statement-terminator-p () ; Should we pass in LIM here? + ;; Does point immediately follow a statement "terminator"? A virtual + ;; semicolon is regarded here as such. So is a an opening brace ;-) + ;; + ;; This function might do hidden buffer changes. + (or (save-excursion + (backward-char) + (and (looking-at "[;{}]") + (not (and c-special-brace-lists ; Pike special brace lists. + (eq (char-after) ?{) + (c-looking-at-special-brace-list))))) + (c-at-vsemi-p) + ;; The following (for macros) is not strict about exactly where we are + ;; wrt white space at the end of the macro. Doesn't seem to matter too + ;; much. ACM 2004/3/29. + (let (eom) + (save-excursion + (if (c-beginning-of-macro) + (setq eom (progn (c-end-of-macro) + (point))))) + (when eom + (save-excursion + (c-forward-comments) + (>= (point) eom)))))) + +(defun c-back-over-illiterals (macro-start) + ;; Move backwards over code which isn't a literal (i.e. comment or string), + ;; stopping before reaching BOB or a literal or the boundary of a + ;; preprocessor statement or the "beginning of a statement". MACRO-START is + ;; the position of the '#' beginning the current preprocessor directive, or + ;; NIL if we're not in such. + ;; + ;; Return a cons (A.B), where + ;; A is NIL if we moved back to a BOS (and know it), T otherwise (we + ;; didn't move, or we hit a literal, or we're not sure about BOS). + ;; B is MACRO-BOUNDARY if we are about to cross the boundary out of or + ;; into a macro, otherwise LITERAL if we've hit a literal, otherwise NIL + ;; + ;; The total collection of returned values is as follows: + ;; (nil . nil): Found a BOS whilst remaining inside the illiterals. + ;; (t . literal): No BOS found: only a comment/string. We _might_ be at + ;; a BOS - the caller must check this. + ;; (nil . macro-boundary): only happens with non-nil macro-start. We've + ;; moved and reached the opening # of the macro. + ;; (t . macro-boundary): Every other circumstance in which we're at a + ;; macro-boundary. We might be at a BOS. + ;; + ;; Point is left either at the beginning-of-statement, or at the last non-ws + ;; code before encountering the literal/BOB or macro-boundary. + ;; + ;; Note that this function moves within either preprocessor commands + ;; (macros) or normal code, but will not cross a boundary between the two, + ;; or between two distinct preprocessor commands. + ;; + ;; Stop before `{' and after `;', `{', `}' and `};' when not followed by `}' + ;; or `)', but on the other side of the syntactic ws. Move by sexps and + ;; move into parens. Also stop before `#' when it's at boi on a line. + ;; + ;; This function might do hidden buffer changes. + (save-match-data + (let ((here (point)) + last) ; marks the position of non-ws code, what'll be BOS if, say, a + ; semicolon precedes it. + (catch 'done + (while t ;; We go back one "token" each iteration of the loop. + (setq last (point)) + (cond + ;; Stop at the token after a comment. + ((c-backward-single-comment) ; Also functions as backwards-ws. + (goto-char last) + (throw 'done '(t . literal))) + + ;; If we've gone back over a LF, we might have moved into or out of + ;; a preprocessor line. + ((and (save-excursion + (beginning-of-line) + (re-search-forward "\\(^\\|[^\\]\\)[\n\r]" last t)) + (if macro-start + (< (point) macro-start) + (c-beginning-of-macro))) + (goto-char last) + ;; Return a car of NIL ONLY if we've hit the opening # of a macro. + (throw 'done (cons (or (eq (point) here) + (not macro-start)) + 'macro-boundary))) + + ;; Have we found a virtual semicolon? If so, stop, unless the next + ;; statement is where we started from. + ((and (c-at-vsemi-p) + (< last here) + (not (memq (char-after last) '(?\) ?})))) ; we've moved back from ) or } + (goto-char last) + (throw 'done '(nil . nil))) + + ;; Hit the beginning of the buffer/region? + ((bobp) + (if (/= here last) + (goto-char last)) + (throw 'done '(nil . nil))) + + ;; Move back a character. + ((progn (backward-char) nil)) + + ;; Stop at "{" (unless it's a PIKE special brace list.) + ((eq (char-after) ?\{) + (if (and c-special-brace-lists + (c-looking-at-special-brace-list)) + (skip-syntax-backward "w_") ; Speedup only. + (if (/= here last) + (goto-char last)) + (throw 'done '(nil . nil)))) + + ;; Have we reached the start of a macro? This always counts as + ;; BOS. (N.B. I don't think (eq (point) here) can ever be true + ;; here. FIXME!!! ACM 2004/3/29) + ((and macro-start (eq (point) macro-start)) + (throw 'done (cons (eq (point) here) 'macro-boundary))) + + ;; Stop at token just after "}" or ";". + ((looking-at "[;}]") + ;; If we've gone back over ;, {, or }, we're done. + (if (or (= here last) + (memq (char-after last) '(?\) ?}))) ; we've moved back from ) or } + (if (and (eq (char-before) ?}) ; If };, treat them as a unit. + (eq (char-after) ?\;)) + (backward-char)) + (goto-char last) ; To the statement starting after the ; or }. + (throw 'done '(nil . nil)))) + + ;; Stop at the token after a string. + ((looking-at c-string-limit-regexp) ; Just gone back over a string terminator? + (goto-char last) + (throw 'done '(t . literal))) + + ;; Nothing special: go back word characters. + (t (skip-syntax-backward "w_")) ; Speedup only. + )))))) + +(defun c-forward-over-illiterals (macro-end allow-early-stop) + ;; Move forwards over code, stopping before reaching EOB or a literal + ;; (i.e. a comment/string) or the boundary of a preprocessor statement or + ;; the "end of a statement". MACRO-END is the position of the EOL/EOB which + ;; terminates the current preprocessor directive, or NIL if we're not in + ;; such. + ;; + ;; ALLOW-EARLY-STOP is non-nil if it is permissible to return without moving + ;; forward at all, should we encounter a `{'. This is an ugly kludge, but + ;; seems unavoidable. Depending on the context this function is called + ;; from, we _sometimes_ need to stop there. Currently (2004/4/3), + ;; ALLOW-EARLY-STOP is applied only to open braces, not to virtual + ;; semicolons, or anything else. + ;; + ;; Return a cons (A.B), where + ;; A is NIL if we moved forward to an EOS, or stay at one (when + ;; ALLOW-EARLY-STOP is set), T otherwise (we hit a literal). + ;; B is 'MACRO-BOUNDARY if we are about to cross the boundary out of or + ;; into a macro, otherwise 'LITERAL if we've hit a literal, otherwise NIL + ;; + ;; Point is left either after the end-of-statement, or at the last non-ws + ;; code before encountering the literal, or the # of the preprocessor + ;; statement, or at EOB [or just after last non-WS stuff??]. + ;; + ;; As a clarification of "after the end-of-statement", if a comment or + ;; whitespace follows a completed AWK statement, that statement is treated + ;; as ending just after the last non-ws character before the comment. + ;; + ;; Note that this function moves within either preprocessor commands + ;; (macros) or normal code, but not both within the same invocation. + ;; + ;; Stop before `{', `}', and `#' when it's at boi on a line, but on the + ;; other side of the syntactic ws, and after `;', `}' and `};'. Only + ;; stop before `{' if at top level or inside braces, though. Move by + ;; sexps and move into parens. Also stop at eol of lines with `#' at + ;; the boi. + ;; + ;; This function might do hidden buffer changes. + (let ((here (point)) + last) + (catch 'done + (while t ;; We go one "token" forward each time round this loop. + (setq last (point)) + + ;; If we've moved forward to a virtual semicolon, we're done. + (if (and (> last here) ; Should we check ALLOW-EARLY-STOP, here? 2004/4/3 + (c-at-vsemi-p)) + (throw 'done '(nil . nil))) + + (c-skip-ws-forward) + (cond + ;; Gone past the end of a macro? + ((and macro-end (> (point) macro-end)) + (goto-char last) + (throw 'done (cons (eq (point) here) 'macro-boundary))) + + ;; About to hit a comment? + ((save-excursion (c-forward-single-comment)) + (goto-char last) + (throw 'done '(t . literal))) + + ;; End of buffer? + ((eobp) + (if (/= here last) + (goto-char last)) + (throw 'done '(nil . nil))) + + ;; If we encounter a '{', stop just after the previous token. + ((and (eq (char-after) ?{) + (not (and c-special-brace-lists + (c-looking-at-special-brace-list))) + (or allow-early-stop (/= here last)) + (save-excursion ; Is this a check that we're NOT at top level? +;;;; NO! This seems to check that (i) EITHER we're at the top level; OR (ii) The next enclosing +;;;; level of bracketing is a '{'. HMM. Doesn't seem to make sense. +;;;; 2003/8/8 This might have something to do with the GCC extension "Statement Expressions", e.g. +;;;; while ({stmt1 ; stmt2 ; exp ;}). This form excludes such Statement Expressions. + (or (not (c-safe (up-list -1) t)) + (= (char-after) ?{)))) + (goto-char last) + (throw 'done '(nil . nil))) + + ;; End of a PIKE special brace list? If so, step over it and continue. + ((and c-special-brace-lists + (eq (char-after) ?}) + (save-excursion + (and (c-safe (up-list -1) t) + (c-looking-at-special-brace-list)))) + (forward-char) + (skip-syntax-forward "w_")) ; Speedup only. + + ;; Have we got a '}' after having moved? If so, stop after the + ;; previous token. + ((and (eq (char-after) ?}) + (/= here last)) + (goto-char last) + (throw 'done '(nil . nil))) + + ;; Stop if we encounter a preprocessor line. + ((and (not macro-end) + (eq (char-after) ?#) + (= (point) (c-point 'boi))) + (goto-char last) + ;(throw 'done (cons (eq (point) here) 'macro-boundary))) ; Changed 2003/3/26 + (throw 'done '(t . macro-boundary))) + + ;; Stop after a ';', '}', or "};" + ((looking-at ";\\|};?") + (goto-char (match-end 0)) + (throw 'done '(nil . nil))) + + ;; Found a string (this subsumes AWK regexps)? + ((looking-at c-string-limit-regexp) + (goto-char last) + (throw 'done '(t . literal))) + + (t + (forward-char) ; Can't fail - we checked (eobp) earlier on. + (skip-syntax-forward "w_") ; Speedup only. + (when (and macro-end (> (point) macro-end)) + (goto-char last) + (throw 'done (cons (eq (point) here) 'macro-boundary)))) + ))))) + +(defun c-one-line-string-p (range) + ;; Is the literal defined by RANGE a string contained in a single line? + ;; + ;; This function might do hidden buffer changes. + (save-excursion + (goto-char (car range)) + (and (looking-at c-string-limit-regexp) + (progn (skip-chars-forward "^\n" (cdr range)) + (eq (point) (cdr range)))))) + (defun c-beginning-of-statement (&optional count lim sentence-flag) "Go to the beginning of the innermost C statement. With prefix arg, go back N - 1 statements. If already at the @@ -1382,318 +2247,93 @@ to search for the syntactic context, and a flag saying whether to do sentence motion in or near comments and multiline strings. -Note that `c-beginning-of-statement-1' is usually better to use from -programs. It has much more well defined semantics than this one, -which is intended for interactive use and might therefore change to be -more \"DWIM:ey\"." +Note that for use in programs, `c-beginning-of-statement-1' is +usually better. It has much better defined semantics than this one, +which is intended for interactive use, and might therefore change to +be more \"DWIM:ey\"." (interactive (list (prefix-numeric-value current-prefix-arg) nil t)) - (c-save-buffer-state - ((count (or count 1)) - here - (range (c-collect-line-comments (c-literal-limits lim)))) - (while (and (/= count 0) - (or (not lim) (> (point) lim))) - (setq here (point)) - (if (and (not range) sentence-flag) - (save-excursion - ;; Find the comment next to point if we're not in one. - (if (> count 0) - (if (c-backward-single-comment) - (setq range (cons (point) - (progn (c-forward-single-comment) - (point)))) - (c-skip-ws-backward) - (setq range (point)) - (setq range - (if (eq (char-before) ?\") - (c-safe (c-backward-sexp 1) - (cons (point) range))))) - (c-skip-ws-forward) - (if (eq (char-after) ?\") - (setq range (cons (point) - (progn - (c-forward-sexp 1) - (point)))) - (setq range (point)) - (setq range (if (c-forward-single-comment) - (cons range (point)) - nil)))) - (setq range (c-collect-line-comments range)))) - (if (and (< count 0) (= here (point-max))) - ;; Special case because eob might be in a literal. - (setq range nil)) - (if range - (if (and sentence-flag - (or (/= (char-syntax (char-after (car range))) ?\") - ;; Only visit a string if it spans more than one line. - (save-excursion - (goto-char (car range)) - (skip-chars-forward "^\n" (cdr range)) - (< (point) (cdr range))))) - (let* ((lit-type (c-literal-type range)) - (line-prefix (concat "[ \t]*\\(" - c-current-comment-prefix - "\\)[ \t]*")) - (beg (if (eq lit-type 'string) - (1+ (car range)) - (save-excursion - (goto-char (car range)) - (max (progn - (looking-at comment-start-skip) - (match-end 0)) - (progn - (looking-at line-prefix) - (match-end 0)))))) - (end (- (cdr range) (if (eq lit-type 'c) 2 1))) - (beg-of-para (if (eq lit-type 'string) - (lambda ()) - (lambda () - (beginning-of-line) - (if (looking-at line-prefix) - (goto-char (match-end 0))))))) - (save-restriction - ;; Move by sentence, but not past the limit of the - ;; literal, narrowed to the appropriate - ;; paragraph(s). - (narrow-to-region (save-excursion - (let ((pos (min here end))) - (goto-char pos) - (forward-paragraph -1) - (if (looking-at paragraph-separate) - (forward-line)) - (when (> (point) beg) - (funcall beg-of-para) - (when (>= (point) pos) - (forward-paragraph -2) - (funcall beg-of-para))) - (max (point) beg))) - end) - (c-safe (forward-sentence (if (< count 0) 1 -1))) - (if (and (memq lit-type '(c c++)) - ;; Check if we stopped due to a comment - ;; prefix and not a sentence end. - (/= (point) (point-min)) - (/= (point) (point-max)) - (save-excursion - (beginning-of-line) - (looking-at line-prefix)) - (>= (point) (match-beginning 0)) - (/= (match-beginning 1) (match-end 1)) - (or (< (point) (match-end 0)) - (and - (= (point) (match-end 0)) - ;; The comment prefix may contain - ;; characters that is regarded as end - ;; of sentence. - (or (eolp) - (and - (save-excursion - (forward-paragraph -1) - (< (point) (match-beginning 0))) - (save-excursion - (beginning-of-line) - (or (not (re-search-backward - (sentence-end) - (c-point 'bopl) - t)) - (< (match-end 0) - (c-point 'eol))))))))) - (setq count (+ count (if (< count 0) -1 1))) - (if (< count 0) - (progn - ;; In block comments, if there's only - ;; horizontal ws between the text and the - ;; comment ender, stop before it. Stop after - ;; the ender if there's either nothing or - ;; newlines between. - (when (and (eq lit-type 'c) - (eq (point) (point-max))) - (widen) - (when (or (= (skip-chars-backward " \t") 0) - (eq (point) (point-max)) - (bolp)) - (goto-char (cdr range))))) - (when (and (eq (point) (point-min)) - (looking-at "[ \t]*\\\\?$")) - ;; Stop before instead of after the comment - ;; starter if nothing follows it. - (widen) - (goto-char (car range)) - (if (and (eq lit-type 'string) (/= (point) here)) - (setq count (1+ count) - range nil)))))) - ;; See if we should escape the literal. - (if (> count 0) - (if (< (point) here) - (setq count (1- count)) - (goto-char (car range)) - (setq range nil)) - (if (> (point) here) - (setq count (1+ count)) - (goto-char (cdr range)) - (setq range nil)))) - (goto-char (if (> count 0) (car range) (cdr range))) - (setq range nil)) - (goto-char here) - (if (> count 0) - (condition-case nil - ;; Stop before `{' and after `;', `{', `}' and `};' - ;; when not followed by `}' or `)', but on the other - ;; side of the syntactic ws. Move by sexps and move - ;; into parens. Also stop before `#' when it's at boi - ;; on a line. - (let ((literal-pos (not sentence-flag)) - last last-below-line) - (catch 'done - (while t - (setq last (point)) - (when (and (or (eq (char-after) ?\{) - (and (eq (char-after) ?#) - (eq (point) (c-point 'boi))) - ) - (/= here last)) - (unless (and c-special-brace-lists - (eq (char-after) ?{) - (c-looking-at-special-brace-list)) - (if (and (eq (char-after) ?#) - (numberp last-below-line) - (not (eq last-below-line here))) - (goto-char last-below-line)) - (throw 'done t))) - ;; Don't know why I added the following, but it - ;; doesn't work when point is preceded by a line - ;; style comment. /mast - ;;(c-skip-ws-backward) - (if literal-pos - (c-backward-comments) - (when (c-backward-single-comment) - ;; Record position of first comment. - (save-excursion - (c-forward-single-comment) - (setq literal-pos (point))) - (c-backward-comments))) - (unless last-below-line - (if (save-excursion - (re-search-forward "\\(^\\|[^\\]\\)$" last t)) - (setq last-below-line last))) - (cond ((bobp) ; Must handle bob specially. - (if (= here last) - (throw 'done t) - (goto-char last) - (throw 'done t))) - ((progn (backward-char) - (looking-at "[;{}]")) - (if (and c-special-brace-lists - (eq (char-after) ?{) - (c-looking-at-special-brace-list)) - (skip-syntax-backward "w_") ; Speedup only. - (if (or (= here last) - (memq (char-after last) '(?\) ?}))) - (if (and (eq (char-before) ?}) - (eq (char-after) ?\;)) - (backward-char)) - (goto-char last) - (throw 'done t)))) - ((= (char-syntax (char-after)) ?\") - (let ((end (point))) - (forward-char) - (c-backward-sexp) - (save-excursion - (skip-chars-forward "^\n" end) - (when (< (point) end) - ;; Break at multiline string. - (setq literal-pos (1+ end)) - (throw 'done t))))) - (t (skip-syntax-backward "w_")) ; Speedup only. - ))) - (if (and (numberp literal-pos) - (< (point) literal-pos)) - ;; We jumped over a comment or string that - ;; should be investigated. - (goto-char literal-pos) - (setq count (1- count)))) - (error - (goto-char (point-min)) - (setq count 0))) - (condition-case nil - ;; Stop before `{', `}', and `#' when it's at boi on a - ;; line, but on the other side of the syntactic ws, and - ;; after `;', `}' and `};'. Only stop before `{' if at - ;; top level or inside braces, though. Move by sexps - ;; and move into parens. Also stop at eol of lines - ;; with `#' at the boi. - (let ((literal-pos (not sentence-flag)) - last) - (catch 'done - (while t - (setq last (point)) - (if literal-pos - (c-forward-comments) - (if (progn - (c-skip-ws-forward) - ;; Record position of first comment. - (setq literal-pos (point)) - (c-forward-single-comment)) - (c-forward-comments) - (setq literal-pos nil))) - (cond ((and (eq (char-after) ?{) - (not (and c-special-brace-lists - (c-looking-at-special-brace-list))) - (/= here last) - (save-excursion - (or (not (c-safe (up-list -1) t)) - (= (char-after) ?{)))) - (goto-char last) - (throw 'done t)) - ((and c-special-brace-lists - (eq (char-after) ?}) - (save-excursion - (and (c-safe (up-list -1) t) - (c-looking-at-special-brace-list)))) - (forward-char 1) - (skip-syntax-forward "w_")) ; Speedup only. - ((and (eq (char-after) ?}) - (/= here last)) - (goto-char last) - (throw 'done t)) -; ((and (eq (char-after) ?#) -; (= (point) (c-point 'boi))) -; (if (= here last) -; (or (re-search-forward "\\(^\\|[^\\]\\)$" nil t) -; (goto-char (point-max))) -; (goto-char last)) -; (throw 'done t)) - ((looking-at ";\\|};?") - (goto-char (match-end 0)) - (throw 'done t)) - ((= (char-syntax (char-after)) ?\") - (let ((beg (point))) - (c-forward-sexp) - (save-excursion - (skip-chars-backward "^\n" beg) - (when (> (point) beg) - ;; Break at multiline string. - (setq literal-pos beg) - (throw 'done t))))) - (t - (forward-char 1) - (skip-syntax-forward "w_")) ; Speedup only. - ))) - (if (and (numberp literal-pos) - (> (point) literal-pos)) - ;; We jumped over a comment that should be investigated. - (goto-char literal-pos) - (setq count (1+ count)))) - (error - (goto-char (point-max)) - (setq count 0))) - )) - ;; If we haven't moved we're near a buffer limit. - (when (and (not (zerop count)) (= (point) here)) - (goto-char (if (> count 0) (point-min) (point-max))) - (setq count 0)))) - (c-keep-region-active)) + (if (< count 0) + (c-end-of-statement (- count) lim sentence-flag) + (c-save-buffer-state + ((count (or count 1)) + last ; start point for going back ONE chunk. Updated each chunk movement. + (macro-fence + (save-excursion (and (not (bobp)) (c-beginning-of-macro) (point)))) + res ; result from sub-function call + not-bos ; "not beginning-of-statement" + (range (c-collect-line-comments (c-literal-limits lim)))) ; (start.end) of current literal or NIL + + ;; Go back one statement at each iteration of the following loop. + (while (and (/= count 0) + (or (not lim) (> (point) lim))) + ;; Go back one "chunk" each time round the following loop, stopping + ;; when we reach a statement boundary, etc. + (setq last (point)) + (while + (cond ; Each arm of this cond returns NIL on reaching a desired + ; statement boundary, non-NIL otherwise. + ((bobp) + (setq count 0) + nil) + + (range ; point is within or approaching a literal. + (cond + ;; Single line string or sentence-flag is null => skip the + ;; entire literal. + ((or (null sentence-flag) + (c-one-line-string-p range)) + (goto-char (car range)) + (setq range (c-ascertain-preceding-literal)) + ;; N.B. The following is essentially testing for an AWK regexp + ;; at BOS: + ;; Was the previous non-ws thing an end of statement? + (save-excursion + (if macro-fence + (c-backward-comments) + (c-backward-syntactic-ws)) + (not (or (bobp) (c-after-statement-terminator-p))))) + + ;; Comment inside a statement or a multi-line string. + (t (when (setq res ; returns non-nil when we go out of the literal + (if (eq (c-literal-type range) 'string) + (c-beginning-of-sentence-in-string range) + (c-beginning-of-sentence-in-comment range))) + (setq range (c-ascertain-preceding-literal))) + res))) + + ;; Non-literal code. + (t (setq res (c-back-over-illiterals macro-fence)) + (setq not-bos ; "not reached beginning-of-statement". + (or (= (point) last) + (memq (char-after) '(?\) ?\})) + (and + (car res) + ;; We're at a tentative BOS. The next form goes + ;; back over WS looking for an end of previous + ;; statement. + (not (save-excursion + (if macro-fence + (c-backward-comments) + (c-backward-syntactic-ws)) + (or (bobp) (c-after-statement-terminator-p))))))) + ;; Are we about to move backwards into or out of a + ;; preprocessor command? If so, locate it's beginning. + (when (eq (cdr res) 'macro-boundary) + (save-excursion + (beginning-of-line) + (setq macro-fence + (and (not (bobp)) + (progn (c-skip-ws-backward) (c-beginning-of-macro)) + (point))))) + ;; Are we about to move backwards into a literal? + (when (memq (cdr res) '(macro-boundary literal)) + (setq range (c-ascertain-preceding-literal))) + not-bos)) + (setq last (point))) + + (if (/= count 0) (setq count (1- count)))) + (c-keep-region-active)))) (defun c-end-of-statement (&optional count lim sentence-flag) "Go to the end of the innermost C statement. @@ -1708,8 +2348,77 @@ sentence motion in or near comments and multiline strings." (interactive (list (prefix-numeric-value current-prefix-arg) nil t)) - (c-beginning-of-statement (- (or count 1)) lim sentence-flag) - (c-keep-region-active)) + (setq count (or count 1)) + (if (< count 0) (c-beginning-of-statement (- count) lim sentence-flag) + + (c-save-buffer-state + (here ; start point for going forward ONE statement. Updated each statement. + (macro-fence + (save-excursion + (and (not (eobp)) (c-beginning-of-macro) + (progn (c-end-of-macro) (point))))) + res + (range (c-collect-line-comments (c-literal-limits lim)))) ; (start.end) of current literal or NIL + + ;; Go back/forward one statement at each iteration of the following loop. + (while (and (/= count 0) + (or (not lim) (< (point) lim))) + (setq here (point)) ; ONLY HERE is HERE updated + + ;; Go forward one "chunk" each time round the following loop, stopping + ;; when we reach a statement boundary, etc. + (while + (cond ; Each arm of this cond returns NIL on reaching a desired + ; statement boundary, non-NIL otherwise. + ((eobp) + (setq count 0) + nil) + + (range ; point is within a literal. + (cond + ;; sentence-flag is null => skip the entire literal. + ;; or a Single line string. + ((or (null sentence-flag) + (c-one-line-string-p range)) + (goto-char (cdr range)) + (setq range (c-ascertain-following-literal)) + ;; Is there a virtual semicolon here (e.g. for AWK)? + (not (c-at-vsemi-p))) + + ;; Comment or multi-line string. + (t (when (setq res ; gets non-nil when we go out of the literal + (if (eq (c-literal-type range) 'string) + (c-end-of-sentence-in-string range) + (c-end-of-sentence-in-comment range))) + (setq range (c-ascertain-following-literal))) + ;; If we've just come forward out of a literal, check for + ;; vsemi. (N.B. AWK can't have a vsemi after a comment, but + ;; some other language may do in the future) + (and res + (not (c-at-vsemi-p)))))) + + ;; Non-literal code. + (t (setq res (c-forward-over-illiterals macro-fence + (> (point) here))) + ;; Are we about to move forward into or out of a + ;; preprocessor command? + (when (eq (cdr res) 'macro-boundary) + (save-excursion + (end-of-line) + (setq macro-fence + (and (not (eobp)) + (progn (c-skip-ws-forward) + (c-beginning-of-macro)) + (progn (c-end-of-macro) + (point)))))) + ;; Are we about to move forward into a literal? + (when (memq (cdr res) '(macro-boundary literal)) + (setq range (c-ascertain-following-literal))) + (car res)))) + + (if (/= count 0) (setq count (1- count)))) + (c-keep-region-active)))) + ;; set up electric character functions to work with pending-del, @@ -1737,6 +2446,7 @@ (defun c-calc-comment-indent (entry) + ;; This function might do hidden buffer changes. (if (symbolp entry) (setq entry (or (assq entry c-indent-comment-alist) (assq 'other c-indent-comment-alist) @@ -1760,7 +2470,7 @@ (let ((lim (c-literal-limits (c-point 'bol) t))) (when (consp lim) (goto-char (car lim)) - (when (looking-at "/[/*]") + (when (looking-at "/[/*]") ; FIXME!!! Adapt for AWK! (ACM, 2005/11/18) ;; Found comment to align with. (if (bolp) ;; Do not pad with one space if we're at bol. @@ -1835,15 +2545,16 @@ A prefix argument acts as a repeat count. With a negative argument, move forward to the end of the containing preprocessor conditional. -`#elif' is treated like `#else' followed by `#if', so the function -stops at them when going backward, but not when going forward." +\"#elif\" is treated like \"#else\" followed by \"#if\", so the +function stops at them when going backward, but not when going +forward." (interactive "p") (c-forward-conditional (- count) -1) (c-keep-region-active)) (defun c-up-conditional-with-else (count) - "Move back to the containing preprocessor conditional, including `#else'. -Just like `c-up-conditional', except it also stops at `#else' + "Move back to the containing preprocessor conditional, including \"#else\". +Just like `c-up-conditional', except it also stops at \"#else\" directives." (interactive "p") (c-forward-conditional (- count) -1 t) @@ -1854,15 +2565,16 @@ A prefix argument acts as a repeat count. With a negative argument, move backward into the previous preprocessor conditional. -`#elif' is treated like `#else' followed by `#if', so the function -stops at them when going forward, but not when going backward." +\"#elif\" is treated like \"#else\" followed by \"#if\", so the +function stops at them when going forward, but not when going +backward." (interactive "p") (c-forward-conditional count 1) (c-keep-region-active)) (defun c-down-conditional-with-else (count) - "Move forward into the next preprocessor conditional, including `#else'. -Just like `c-down-conditional', except it also stops at `#else' + "Move forward into the next preprocessor conditional, including \"#else\". +Just like `c-down-conditional', except it also stops at \"#else\" directives." (interactive "p") (c-forward-conditional count 1 t) @@ -1881,16 +2593,16 @@ A prefix argument acts as a repeat count. With a negative argument, move backward across a preprocessor conditional. -`#elif' is treated like `#else' followed by `#if', except that the -nesting level isn't changed when tracking subconditionals. +\"#elif\" is treated like \"#else\" followed by \"#if\", except that +the nesting level isn't changed when tracking subconditionals. The optional argument TARGET-DEPTH specifies the wanted nesting depth after each scan. I.e. if TARGET-DEPTH is -1, the function will move out of the enclosing conditional. A non-integer non-nil TARGET-DEPTH counts as -1. -If the optional argument WITH-ELSE is non-nil, `#else' directives are -treated as conditional clause limits. Normally they are ignored." +If the optional argument WITH-ELSE is non-nil, \"#else\" directives +are treated as conditional clause limits. Normally they are ignored." (interactive "p") (let* ((forward (> count 0)) (increment (if forward -1 1)) @@ -1996,15 +2708,15 @@ just inserts a tab character, or the equivalent number of spaces, depending on the variable `indent-tabs-mode'." - (interactive "p") + (interactive "P") (let ((indent-function (if c-syntactic-indentation (symbol-function 'indent-according-to-mode) (lambda () (let ((c-macro-start c-macro-start) - (steps (cond ((not current-prefix-arg) 1) - ((equal current-prefix-arg '(4)) -1) - (t arg)))) + (steps (if (equal arg '(4)) + -1 + (prefix-numeric-value arg)))) (c-shift-line-indentation (* steps c-basic-offset)) (when (and c-auto-align-backslashes (save-excursion @@ -2014,7 +2726,7 @@ ;; Realign the line continuation backslash if inside a macro. (c-backslash-region (point) (point) nil t))) )))) - (if (and c-syntactic-indentation current-prefix-arg) + (if (and c-syntactic-indentation arg) ;; If c-syntactic-indentation and got arg, always indent this ;; line as C and shift remaining lines of expression the same ;; amount. @@ -2029,7 +2741,7 @@ shift-amt)) (save-excursion (if (eq c-tab-always-indent t) - (beginning-of-line)) + (beginning-of-line)) ; FIXME!!! What is this here for? ACM 2005/10/31 (setq beg (point)) (c-forward-sexp 1) (setq end (point)) @@ -2040,7 +2752,7 @@ (indent-code-rigidly beg end shift-amt "#"))) ;; Else use c-tab-always-indent to determine behavior. (cond - ;; CASE 1: indent when at column zero or in lines indentation, + ;; CASE 1: indent when at column zero or in line's indentation, ;; otherwise insert a tab ((not c-tab-always-indent) (if (save-excursion @@ -2054,7 +2766,7 @@ ;; CASE 3: if in a literal, insert a tab, but always indent the ;; line (t - (if (c-in-literal) + (if (c-save-buffer-state () (c-in-literal)) (funcall c-insert-tab-function)) (funcall indent-function) ))))) @@ -2135,7 +2847,8 @@ ;; shut up any echo msgs on indiv lines (c-echo-syntactic-information-p nil) (in-macro (and c-auto-align-backslashes - (save-excursion (c-beginning-of-macro)) + (c-save-buffer-state () + (save-excursion (c-beginning-of-macro))) start)) (c-fix-backslashes nil) syntax) @@ -2181,8 +2894,6 @@ (defun c-fn-region-is-active-p () ;; Function version of the macro for use in places that aren't ;; compiled, e.g. in the menus. - ;; - ;; This function does not do any hidden buffer changes. (c-region-is-active-p)) (defun c-indent-line-or-region () @@ -2199,7 +2910,6 @@ (defvar c-progress-info nil) (defun c-progress-init (start end context) - ;; This function does not do any hidden buffer changes. (cond ;; Be silent ((not c-progress-interval)) @@ -2221,7 +2931,6 @@ )) (defun c-progress-update () - ;; This function does not do any hidden buffer changes. (if (not (and c-progress-info c-progress-interval)) nil (let ((now (nth 1 (current-time))) @@ -2238,7 +2947,6 @@ ))) (defun c-progress-fini (context) - ;; This function does not do any hidden buffer changes. (if (not c-progress-interval) nil (if (or (eq context (aref c-progress-info 3)) @@ -2399,7 +3107,6 @@ (set-marker point-pos nil)))) (defun c-append-backslashes-forward (to-mark column point-pos) - ;; This function does not do any hidden buffer changes. (let ((state (parse-partial-sexp (c-point 'bol) (point)))) (if column (while @@ -2473,7 +3180,6 @@ (bolp)))))) ; forward-line has funny behavior at eob. (defun c-delete-backslashes-forward (to-mark point-pos) - ;; This function does not do any hidden buffer changes. (while (and (<= (point) to-mark) (progn @@ -2518,6 +3224,8 @@ ;; comment. Return a cons of the prefix string and the column where ;; it ends. If fill-prefix is set, it'll override. Note that this ;; function also uses the value of point in some heuristics. + ;; + ;; This function might do hidden buffer changes. (let* ((here (point)) (prefix-regexp (concat "[ \t]*\\(" @@ -2877,7 +3585,7 @@ ;; If APPLY-OUTSIDE-LITERAL is nil then the function will be called ;; only if the point turns out to be inside a comment or a string. ;; - ;; This function does not do any hidden buffer changes. + ;; Note that this function does not do any hidden buffer changes. (let (fill ;; beg and end limits the region to narrow. end is a marker. @@ -2892,6 +3600,10 @@ ;; hanging. In that case it's set to the number of spaces ;; that should be between the text and the ender. hang-ender-stuck + ;; auto-fill-spaces is the exact sequence of whitespace between a + ;; comment's last word and the comment ender, temporarily replaced + ;; with 'x's before calling FUN when FILL-PARAGRAPH is nil. + auto-fill-spaces (here (point)) (c-lit-limits c-lit-limits) (c-lit-type c-lit-type)) @@ -2902,29 +3614,30 @@ (if (and buffer-undo-list (not (eq buffer-undo-list t))) (setq buffer-undo-list (cons (point) buffer-undo-list))) - (save-restriction - ;; Widen to catch comment limits correctly. - (widen) - (unless c-lit-limits - (setq c-lit-limits (c-literal-limits nil fill-paragraph))) - (setq c-lit-limits (c-collect-line-comments c-lit-limits)) - (unless c-lit-type - (setq c-lit-type (c-literal-type c-lit-limits)))) - - (save-excursion - (unless (c-safe (backward-char) - (forward-paragraph) - (>= (point) here)) - (goto-char here) - (forward-paragraph)) - (setq end (point-marker))) - (save-excursion - (unless (c-safe (forward-char) - (backward-paragraph) - (<= (point) here)) - (goto-char here) - (backward-paragraph)) - (setq beg (point))) + (c-save-buffer-state () + (save-restriction + ;; Widen to catch comment limits correctly. + (widen) + (unless c-lit-limits + (setq c-lit-limits (c-literal-limits nil fill-paragraph))) + (setq c-lit-limits (c-collect-line-comments c-lit-limits)) + (unless c-lit-type + (setq c-lit-type (c-literal-type c-lit-limits)))) + + (save-excursion + (unless (c-safe (backward-char) + (forward-paragraph) + (>= (point) here)) + (goto-char here) + (forward-paragraph)) + (setq end (point-marker))) + (save-excursion + (unless (c-safe (forward-char) + (backward-paragraph) + (<= (point) here)) + (goto-char here) + (backward-paragraph)) + (setq beg (point)))) (unwind-protect (progn @@ -2965,73 +3678,76 @@ ;; own. Keep it that way. (set-marker end (point)))) - (if fill-paragraph - ;; The comment ender should hang. Replace all - ;; cruft between it and the last word with one or - ;; two 'x' and include it in the region. We'll - ;; change them back to spaces afterwards. This - ;; isn't done when auto filling, since that'd - ;; effectively make it impossible to insert extra - ;; spaces before the comment ender. - (let* ((ender-start (save-excursion - (goto-char (cdr c-lit-limits)) - (skip-syntax-backward "^w ") - (point))) - (point-rel (- ender-start here)) - spaces) - - (save-excursion - (goto-char (cdr c-lit-limits)) - (setq tmp-post (point-marker)) - (insert ?\n) - (set-marker end (point)) - (forward-line -1) - (if (and (looking-at (concat "[ \t]*\\(\\(" - c-current-comment-prefix - "\\)[ \t]*\\)")) - (eq ender-start (match-end 0))) - ;; The comment ender is prefixed by nothing - ;; but a comment line prefix. Remove it - ;; along with surrounding ws. - (setq spaces (- (match-end 1) (match-end 2))) - (goto-char ender-start)) - (skip-chars-backward " \t\r\n") - - (if (/= (point) ender-start) - (progn - (if (<= here (point)) - ;; Don't adjust point below if it's - ;; before the string we replace. - (setq point-rel -1)) - ;; Keep one or two spaces between the - ;; text and the ender, depending on how - ;; many there are now. - (unless spaces - (setq spaces (- ender-start (point)))) + ;; The comment ender should hang. Replace all space between + ;; it and the last word either by one or two 'x's (when + ;; FILL-PARAGRAPH is non-nil), or a row of x's the same width + ;; as the whitespace (when auto filling), and include it in + ;; the region. We'll change them back to whitespace + ;; afterwards. The effect of this is to glue the comment + ;; ender to the last word in the comment during filling. + (let* ((ender-start (save-excursion + (goto-char (cdr c-lit-limits)) + (skip-syntax-backward "^w ") + (point))) + (ender-column (save-excursion + (goto-char ender-start) + (current-column))) + (point-rel (- ender-start here)) + spaces) + + (save-excursion + (goto-char (cdr c-lit-limits)) + (setq tmp-post (point-marker)) + (insert ?\n) + (set-marker end (point)) + (forward-line -1) ; last line of the comment + (if (and (looking-at (concat "[ \t]*\\(\\(" + c-current-comment-prefix + "\\)[ \t]*\\)")) + (eq ender-start (match-end 0))) + ;; The comment ender is prefixed by nothing + ;; but a comment line prefix. Remove it + ;; along with surrounding ws. + (setq spaces (- (match-end 1) (match-end 2))) + (goto-char ender-start)) + (skip-chars-backward " \t\r\n") ; Surely this can be + ; " \t"? "*/" is NOT alone on the line (ACM, 2005/8/18) + + (if (/= (point) ender-start) + (progn + (if (<= here (point)) + ;; Don't adjust point below if it's + ;; before the string we replace. + (setq point-rel -1)) + ;; Keep one or two spaces between the + ;; text and the ender, depending on how + ;; many there are now. + (unless spaces + (setq spaces (- ender-column (current-column)))) + (setq auto-fill-spaces (c-delete-and-extract-region + (point) ender-start)) + ;; paragraph filling condenses multiple spaces to + ;; single or double spaces. auto-fill doesn't. + (if fill-paragraph (setq spaces (max (min spaces (if sentence-end-double-space 2 1)) - 1)) - ;; Insert the filler first to keep marks right. - (insert-char ?x spaces t) - (delete-region (point) (+ ender-start spaces)) - (setq hang-ender-stuck spaces) - (setq point-rel - (and (>= point-rel 0) - (- (point) (min point-rel spaces))))) - (setq point-rel nil))) - - (if point-rel - ;; Point was in the middle of the string we - ;; replaced above, so put it back in the same - ;; relative position, counting from the end. - (goto-char point-rel))) - - ;; We're doing auto filling. Just move the marker - ;; to the comment end to ignore any code after the - ;; comment. - (move-marker end (cdr c-lit-limits))))) + 1))) + ;; Insert the filler first to keep marks right. + (insert-char ?x spaces t) + (setq hang-ender-stuck spaces) + (setq point-rel + (and (>= point-rel 0) + (- (point) (min point-rel spaces))))) + (setq point-rel nil))) + + (if point-rel + ;; Point was in the middle of the string we + ;; replaced above, so put it back in the same + ;; relative position, counting from the end. + (goto-char point-rel))) + )) (when (<= beg (car c-lit-limits)) ;; The region includes the comment starter. @@ -3068,14 +3784,15 @@ ;; inside macros is bogus to begin with since the line ;; continuation backslashes aren't handled). (save-excursion - (c-beginning-of-macro) - (beginning-of-line) - (if (> (point) beg) - (setq beg (point))) - (c-end-of-macro) - (forward-line) - (if (< (point) end) - (set-marker end (point))))) + (c-save-buffer-state () + (c-beginning-of-macro) + (beginning-of-line) + (if (> (point) beg) + (setq beg (point))) + (c-end-of-macro) + (forward-line) + (if (< (point) end) + (set-marker end (point)))))) (t ; Other code. ;; Try to avoid comments and macros in the paragraph to @@ -3192,7 +3909,10 @@ (goto-char tmp-post) (skip-syntax-backward "^w ") (forward-char (- hang-ender-stuck)) - (insert-char ?\ hang-ender-stuck t) + (if (or fill-paragraph (not auto-fill-spaces)) + (insert-char ?\ hang-ender-stuck t) + (insert auto-fill-spaces) + (setq here (- here (- hang-ender-stuck (length auto-fill-spaces))))) (delete-char hang-ender-stuck) (goto-char here)) (set-marker tmp-post nil)) @@ -3233,8 +3953,6 @@ (defun c-do-auto-fill () ;; Do automatic filling if not inside a context where it should be ;; ignored. - ;; - ;; This function does not do any hidden buffer changes. (let ((c-auto-fill-prefix ;; The decision whether the line should be broken is actually ;; done in c-indent-new-comment-line, which do-auto-fill @@ -3274,31 +3992,36 @@ (c-lit-limits c-lit-limits) (c-lit-type c-lit-type) (c-macro-start c-macro-start)) - (when (not (eq c-auto-fill-prefix t)) - ;; Called from do-auto-fill. - (unless c-lit-limits - (setq c-lit-limits (c-literal-limits nil nil t))) - (unless c-lit-type - (setq c-lit-type (c-literal-type c-lit-limits))) - (if (memq (cond ((c-query-and-set-macro-start) 'cpp) - ((null c-lit-type) 'code) - (t c-lit-type)) - c-ignore-auto-fill) - (setq fill-prefix t) ; Used as flag in the cond. - (if (and (null c-auto-fill-prefix) - (eq c-lit-type 'c) - (<= (c-point 'bol) (car c-lit-limits))) - ;; The adaptive fill function has generated a prefix, but - ;; we're on the first line in a block comment so it'll be - ;; wrong. Ignore it to guess a better one below. - (setq fill-prefix nil) - (when (and (eq c-lit-type 'c++) - (not (string-match "\\`[ \t]*//" (or fill-prefix "")))) - ;; Kludge: If the function that adapted the fill prefix - ;; doesn't produce the required comment starter for line - ;; comments, then we ignore it. - (setq fill-prefix nil))) - )) + + (c-save-buffer-state () + (when (not (eq c-auto-fill-prefix t)) + ;; Called from do-auto-fill. + (unless c-lit-limits + (setq c-lit-limits (c-literal-limits nil nil t))) + (unless c-lit-type + (setq c-lit-type (c-literal-type c-lit-limits))) + (if (memq (cond ((c-query-and-set-macro-start) 'cpp) + ((null c-lit-type) 'code) + (t c-lit-type)) + c-ignore-auto-fill) + (setq fill-prefix t) ; Used as flag in the cond. + (if (and (null c-auto-fill-prefix) + (eq c-lit-type 'c) + (<= (c-point 'bol) (car c-lit-limits))) + ;; The adaptive fill function has generated a prefix, but + ;; we're on the first line in a block comment so it'll be + ;; wrong. Ignore it to guess a better one below. + (setq fill-prefix nil) + (when (and (eq c-lit-type 'c++) + (not (string-match (concat "\\`[ \t]*" + c-line-comment-starter) + (or fill-prefix "")))) + ;; Kludge: If the function that adapted the fill prefix + ;; doesn't produce the required comment starter for line + ;; comments, then we ignore it. + (setq fill-prefix nil))) + ))) + (cond ((eq fill-prefix t) ;; A call from do-auto-fill which should be ignored. ) @@ -3306,7 +4029,7 @@ ;; A fill-prefix overrides anything. (funcall do-line-break) (insert-and-inherit fill-prefix)) - ((progn + ((c-save-buffer-state () (unless c-lit-limits (setq c-lit-limits (c-literal-limits))) (unless c-lit-type @@ -3440,31 +4163,38 @@ comment prefix (see the `c-comment-prefix-regexp' and `c-block-comment-prefix' variables for details). The end of a C++-style line comment doesn't count as inside it." + (interactive "*") - (let* ((c-lit-limits (c-literal-limits nil nil t)) - (c-lit-type (c-literal-type c-lit-limits)) + (let* (c-lit-limits c-lit-type (c-macro-start c-macro-start)) - (if (or (eq c-lit-type 'c) - (and (eq c-lit-type 'c++) - (< (save-excursion - (skip-chars-forward " \t") - (point)) - (1- (cdr (setq c-lit-limits - (c-collect-line-comments c-lit-limits)))))) - (and (or (not (looking-at "\\s *$")) - (eq (char-before) ?\\)) - (c-query-and-set-macro-start) - (<= (save-excursion - (goto-char c-macro-start) - (if (looking-at c-opt-cpp-start) - (goto-char (match-end 0))) - (point)) - (point)))) + + (if (c-save-buffer-state () + (setq c-lit-limits (c-literal-limits nil nil t) + c-lit-type (c-literal-type c-lit-limits)) + (or (eq c-lit-type 'c) + (and (eq c-lit-type 'c++) + (< (save-excursion + (skip-chars-forward " \t") + (point)) + (1- (cdr (setq c-lit-limits (c-collect-line-comments + c-lit-limits)))))) + (and (or (not (looking-at "\\s *$")) + (eq (char-before) ?\\)) + (c-query-and-set-macro-start) + (<= (save-excursion + (goto-char c-macro-start) + (if (looking-at c-opt-cpp-start) + (goto-char (match-end 0))) + (point)) + (point))))) + (let ((comment-multi-line t) (fill-prefix nil)) (c-indent-new-comment-line nil t)) + (delete-horizontal-space) (newline) + ;; c-indent-line may look at the current indentation, so let's ;; start out with the same indentation as the previous line. (let ((col (save-excursion @@ -3473,6 +4203,7 @@ (= (forward-line -1) 0))) (current-indentation)))) (indent-to col)) + (indent-according-to-mode)))) (defun c-context-open-line () diff -r 8e25aa911e3e -r 37d0562504bf lisp/progmodes/cc-compat.el --- a/lisp/progmodes/cc-compat.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/progmodes/cc-compat.el Sat Dec 10 21:18:28 2005 +0000 @@ -1,6 +1,7 @@ ;;; cc-compat.el --- cc-mode compatibility with c-mode.el confusion -;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc. +;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, +;; Inc. ;; Authors: 1998- Martin Stjernholm ;; 1994-1999 Barry A. Warsaw @@ -22,7 +23,7 @@ ;; 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 +;; along with this program; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. diff -r 8e25aa911e3e -r 37d0562504bf lisp/progmodes/cc-defs.el --- a/lisp/progmodes/cc-defs.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/progmodes/cc-defs.el Sat Dec 10 21:18:28 2005 +0000 @@ -1,6 +1,7 @@ ;;; cc-defs.el --- compile time definitions for CC Mode -;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc. +;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, +;; Inc. ;; Authors: 1998- Martin Stjernholm ;; 1992-1999 Barry A. Warsaw @@ -24,7 +25,7 @@ ;; 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 +;; along with this program; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. @@ -43,8 +44,8 @@ load-path))) (load "cc-bytecomp" nil t))) -;; `require' in XEmacs doesn't have the third NOERROR argument. -(condition-case nil (require 'regexp-opt) (file-error nil)) +(eval-when-compile (require 'cl)) ; was (cc-external-require 'cl). ACM 2005/11/29. +(cc-external-require 'regexp-opt) ;; Silence the compiler. (cc-bytecomp-defvar c-enable-xemacs-performance-kludge-p) ; In cc-vars.el @@ -55,31 +56,18 @@ (cc-bytecomp-defvar mark-active) ; Emacs (cc-bytecomp-defvar deactivate-mark) ; Emacs (cc-bytecomp-defvar inhibit-point-motion-hooks) ; Emacs -(cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs 20+ +(cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs (cc-bytecomp-defvar text-property-default-nonsticky) ; Emacs 21 -(cc-bytecomp-defvar lookup-syntax-properties) ; XEmacs 21 +(cc-bytecomp-defvar lookup-syntax-properties) ; XEmacs (cc-bytecomp-defun string-to-syntax) ; Emacs 21 -(cc-bytecomp-defun regexp-opt-depth) ; (X)Emacs 20+ ;; cc-fix.el contains compatibility macros that should be used if ;; needed. (eval-and-compile - (if (or (not (fboundp 'functionp)) - (not (condition-case nil - (progn (eval '(char-before)) t) - (error nil))) - (not (condition-case nil - (progn (eval '(char-after)) t) - (error nil))) - (not (fboundp 'when)) - (not (fboundp 'unless)) - (not (fboundp 'regexp-opt)) - (not (cc-bytecomp-fboundp 'regexp-opt-depth)) - (/= (regexp-opt-depth "\\(\\(\\)\\)") 2)) - (cc-load "cc-fix") - (defalias 'c-regexp-opt 'regexp-opt) - (defalias 'c-regexp-opt-depth 'regexp-opt-depth))) + (if (or (/= (regexp-opt-depth "\\(\\(\\)\\)") 2) + (not (fboundp 'push))) + (cc-load "cc-fix"))) (eval-after-load "font-lock" '(if (and (not (featurep 'cc-fix)) ; only load the file once. @@ -99,12 +87,10 @@ font-lock-keywords))) (cc-load "cc-fix"))) -(eval-when-compile (require 'cl)) - ;;; Variables also used at compile time. -(defconst c-version "5.30.10" +(defconst c-version "5.31" "CC Mode version number.") (defconst c-version-sym (intern c-version)) @@ -192,29 +178,29 @@ The current point is used if POINT isn't specified. POSITION can be one of the following symbols: -`bol' -- beginning of line -`eol' -- end of line -`bod' -- beginning of defun -`eod' -- end of defun -`boi' -- beginning of indentation -`ionl' -- indentation of next line -`iopl' -- indentation of previous line -`bonl' -- beginning of next line -`eonl' -- end of next line -`bopl' -- beginning of previous line -`eopl' -- end of previous line +`bol' -- beginning of line +`eol' -- end of line +`bod' -- beginning of defun +`eod' -- end of defun +`boi' -- beginning of indentation +`ionl' -- indentation of next line +`iopl' -- indentation of previous line +`bonl' -- beginning of next line +`eonl' -- end of next line +`bopl' -- beginning of previous line +`eopl' -- end of previous line +`bosws' -- beginning of syntactic whitespace +`eosws' -- end of syntactic whitespace If the referenced position doesn't exist, the closest accessible point -to it is returned. This function does not modify point or mark. - -This function does not do any hidden buffer changes." +to it is returned. This function does not modify the point or the mark." (if (eq (car-safe position) 'quote) (let ((position (eval position))) (cond ((eq position 'bol) - (if (and (fboundp 'line-beginning-position) (not point)) + (if (and (cc-bytecomp-fboundp 'line-beginning-position) (not point)) `(line-beginning-position) `(save-excursion ,@(if point `((goto-char ,point))) @@ -222,7 +208,7 @@ (point)))) ((eq position 'eol) - (if (and (fboundp 'line-end-position) (not point)) + (if (and (cc-bytecomp-fboundp 'line-end-position) (not point)) `(line-end-position) `(save-excursion ,@(if point `((goto-char ,point))) @@ -248,7 +234,7 @@ (point))) ((eq position 'bopl) - (if (and (fboundp 'line-beginning-position) (not point)) + (if (and (cc-bytecomp-fboundp 'line-beginning-position) (not point)) `(line-beginning-position 0) `(save-excursion ,@(if point `((goto-char ,point))) @@ -256,7 +242,7 @@ (point)))) ((eq position 'bonl) - (if (and (fboundp 'line-beginning-position) (not point)) + (if (and (cc-bytecomp-fboundp 'line-beginning-position) (not point)) `(line-beginning-position 2) `(save-excursion ,@(if point `((goto-char ,point))) @@ -264,7 +250,7 @@ (point)))) ((eq position 'eopl) - (if (and (fboundp 'line-end-position) (not point)) + (if (and (cc-bytecomp-fboundp 'line-end-position) (not point)) `(line-end-position 0) `(save-excursion ,@(if point `((goto-char ,point))) @@ -273,7 +259,7 @@ (point)))) ((eq position 'eonl) - (if (and (fboundp 'line-end-position) (not point)) + (if (and (cc-bytecomp-fboundp 'line-end-position) (not point)) `(line-end-position 2) `(save-excursion ,@(if point `((goto-char ,point))) @@ -295,54 +281,138 @@ (back-to-indentation) (point))) + ((eq position 'bosws) + `(save-excursion + ,@(if point `((goto-char ,point))) + (c-backward-syntactic-ws) + (point))) + + ((eq position 'eosws) + `(save-excursion + ,@(if point `((goto-char ,point))) + (c-forward-syntactic-ws) + (point))) + (t (error "Unknown buffer position requested: %s" position)))) - ;;(message "c-point long expansion") + ;; The bulk of this should perhaps be in a function to avoid large + ;; expansions, but this case is not used anywhere in CC Mode (and + ;; probably not anywhere else either) so we only have it to be on + ;; the safe side. + (message "Warning: c-point long expansion") `(save-excursion ,@(if point `((goto-char ,point))) (let ((position ,position)) (cond - ((eq position 'bol) (beginning-of-line)) - ((eq position 'eol) (end-of-line)) - ((eq position 'boi) (back-to-indentation)) - ((eq position 'bod) (c-beginning-of-defun-1)) - ((eq position 'eod) (c-end-of-defun-1)) - ((eq position 'bopl) (forward-line -1)) - ((eq position 'bonl) (forward-line 1)) - ((eq position 'eopl) (progn - (beginning-of-line) - (or (bobp) (backward-char)))) - ((eq position 'eonl) (progn - (forward-line 1) - (end-of-line))) - ((eq position 'iopl) (progn - (forward-line -1) - (back-to-indentation))) - ((eq position 'ionl) (progn - (forward-line 1) - (back-to-indentation))) + ((eq position 'bol) (beginning-of-line)) + ((eq position 'eol) (end-of-line)) + ((eq position 'boi) (back-to-indentation)) + ((eq position 'bod) (c-beginning-of-defun-1)) + ((eq position 'eod) (c-end-of-defun-1)) + ((eq position 'bopl) (forward-line -1)) + ((eq position 'bonl) (forward-line 1)) + ((eq position 'eopl) (progn + (beginning-of-line) + (or (bobp) (backward-char)))) + ((eq position 'eonl) (progn + (forward-line 1) + (end-of-line))) + ((eq position 'iopl) (progn + (forward-line -1) + (back-to-indentation))) + ((eq position 'ionl) (progn + (forward-line 1) + (back-to-indentation))) + ((eq position 'bosws) (c-backward-syntactic-ws)) + ((eq position 'eosws) (c-forward-syntactic-ws)) (t (error "Unknown buffer position requested: %s" position)))) (point)))) +(defmacro c-region-is-active-p () + ;; Return t when the region is active. The determination of region + ;; activeness is different in both Emacs and XEmacs. + (if (cc-bytecomp-fboundp 'region-active-p) + ;; XEmacs. + '(region-active-p) + ;; Emacs. + 'mark-active)) + +(defmacro c-set-region-active (activate) + ;; Activate the region if ACTIVE is non-nil, deactivate it + ;; otherwise. Covers the differences between Emacs and XEmacs. + (if (cc-bytecomp-fboundp 'zmacs-activate-region) + ;; XEmacs. + `(if ,activate + (zmacs-activate-region) + (zmacs-deactivate-region)) + ;; Emacs. + `(setq mark-active ,activate))) + +(defmacro c-delete-and-extract-region (start end) + "Delete the text between START and END and return it." + (if (cc-bytecomp-fboundp 'delete-and-extract-region) + ;; Emacs 21.1 and later + `(delete-and-extract-region ,start ,end) + ;; XEmacs and Emacs 20.x + `(prog1 + (buffer-substring ,start ,end) + (delete-region ,start ,end)))) + (defmacro c-safe (&rest body) ;; safely execute BODY, return nil if an error occurred - ;; - ;; This function does not do any hidden buffer changes. `(condition-case nil (progn ,@body) (error nil))) (put 'c-safe 'lisp-indent-function 0) +(defmacro c-int-to-char (integer) + ;; In GNU Emacs, a character is an integer. In XEmacs, a character is a + ;; type distinct from an integer. Sometimes we need to convert integers to + ;; characters. `c-int-to-char' makes this conversion, if necessary. + (if (fboundp 'int-to-char) + `(int-to-char ,integer) + integer)) + +(defmacro c-sentence-end () + ;; Get the regular expression `sentence-end'. + (if (cc-bytecomp-fboundp 'sentence-end) + ;; Emacs 22: + `(sentence-end) + ;; Emacs <22 + XEmacs + `sentence-end)) + +(defmacro c-default-value-sentence-end () + ;; Get the default value of the variable sentence end. + (if (cc-bytecomp-fboundp 'sentence-end) + ;; Emacs 22: + `(let (sentence-end) (sentence-end)) + ;; Emacs <22 + XEmacs + `(default-value 'sentence-end))) + ;; The following is essentially `save-buffer-state' from lazy-lock.el. ;; It ought to be a standard macro. (defmacro c-save-buffer-state (varlist &rest body) "Bind variables according to VARLIST (in `let*' style) and eval BODY, then restore the buffer state under the assumption that no significant -modification has been made. A change is considered significant if it -affects the buffer text in any way that isn't completely restored -again. Changes in text properties like `face' or `syntax-table' are -considered insignificant. This macro allows text properties to be -changed, even in a read-only buffer. +modification has been made in BODY. A change is considered +significant if it affects the buffer text in any way that isn't +completely restored again. Changes in text properties like `face' or +`syntax-table' are considered insignificant. This macro allows text +properties to be changed, even in a read-only buffer. + +This macro should be placed around all calculations which set +\"insignificant\" text properties in a buffer, even when the buffer is +known to be writeable. That way, these text properties remain set +even if the user undoes the command which set them. + +This macro should ALWAYS be placed around \"temporary\" internal buffer +changes \(like adding a newline to calculate a text-property then +deleting it again\), so that the user never sees them on his +`buffer-undo-list'. See also `c-tentative-buffer-changes'. + +However, any user-visible changes to the buffer \(like auto-newlines\) +must not be within a `c-save-buffer-state', since the user then +wouldn't be able to undo them. The return value is the value of the last form in BODY." `(let* ((modified (buffer-modified-p)) (buffer-undo-list t) @@ -350,12 +420,80 @@ before-change-functions after-change-functions deactivate-mark ,@varlist) - (prog1 (progn ,@body) + (unwind-protect + (progn ,@body) (and (not modified) (buffer-modified-p) (set-buffer-modified-p nil))))) (put 'c-save-buffer-state 'lisp-indent-function 1) +(defmacro c-tentative-buffer-changes (&rest body) + "Eval BODY and optionally restore the buffer contents to the state it +was in before BODY. Any changes are kept if the last form in BODY +returns non-nil. Otherwise it's undone using the undo facility, and +various other buffer state that might be affected by the changes is +restored. That includes the current buffer, point, mark, mark +activation \(similar to `save-excursion'), and the modified state. +The state is also restored if BODY exits nonlocally. + +If BODY makes a change that unconditionally is undone then wrap this +macro inside `c-save-buffer-state'. That way the change can be done +even when the buffer is read-only, and without interference from +various buffer change hooks." + `(let (-tnt-chng-keep + -tnt-chng-state) + (unwind-protect + ;; Insert an undo boundary for use with `undo-more'. We + ;; don't use `undo-boundary' since it doesn't insert one + ;; unconditionally. + (setq buffer-undo-list (cons nil buffer-undo-list) + -tnt-chng-state (c-tnt-chng-record-state) + -tnt-chng-keep (progn ,@body)) + (c-tnt-chng-cleanup -tnt-chng-keep -tnt-chng-state)))) +(put 'c-tentative-buffer-changes 'lisp-indent-function 0) + +(defun c-tnt-chng-record-state () + ;; Used internally in `c-tentative-buffer-changes'. + (vector buffer-undo-list ; 0 + (current-buffer) ; 1 + ;; No need to use markers for the point and mark; if the + ;; undo got out of synch we're hosed anyway. + (point) ; 2 + (mark t) ; 3 + (c-region-is-active-p) ; 4 + (buffer-modified-p))) ; 5 + +(defun c-tnt-chng-cleanup (keep saved-state) + ;; Used internally in `c-tentative-buffer-changes'. + + (let ((saved-undo-list (elt saved-state 0))) + (if (eq buffer-undo-list saved-undo-list) + ;; No change was done afterall. + (setq buffer-undo-list (cdr saved-undo-list)) + + (if keep + ;; Find and remove the undo boundary. + (let ((p buffer-undo-list)) + (while (not (eq (cdr p) saved-undo-list)) + (setq p (cdr p))) + (setcdr p (cdr saved-undo-list))) + + ;; `primitive-undo' will remove the boundary. + (setq saved-undo-list (cdr saved-undo-list)) + (let ((undo-in-progress t)) + (while (not (eq (setq buffer-undo-list + (primitive-undo 1 buffer-undo-list)) + saved-undo-list)))) + + (when (buffer-live-p (elt saved-state 1)) + (set-buffer (elt saved-state 1)) + (goto-char (elt saved-state 2)) + (set-mark (elt saved-state 3)) + (c-set-region-active (elt saved-state 4)) + (and (not (elt saved-state 5)) + (buffer-modified-p) + (set-buffer-modified-p nil))))))) + (defmacro c-forward-syntactic-ws (&optional limit) "Forward skip over syntactic whitespace. Syntactic whitespace is defined as whitespace characters, comments, @@ -402,91 +540,127 @@ This is like `forward-sexp' except that it isn't interactive and does not do any user friendly adjustments of the point and that it isn't susceptible to user configurations such as disabling of signals in -certain situations. - -This function does not do any hidden buffer changes." +certain situations." (or count (setq count 1)) - `(goto-char (or (scan-sexps (point) ,count) - ,(if (numberp count) - (if (> count 0) `(point-max) `(point-min)) - `(if (> ,count 0) (point-max) (point-min)))))) + `(goto-char (scan-sexps (point) ,count))) (defmacro c-backward-sexp (&optional count) "See `c-forward-sexp' and reverse directions." (or count (setq count 1)) `(c-forward-sexp ,(if (numberp count) (- count) `(- ,count)))) -(defmacro c-safe-scan-lists (from count depth) - "Like `scan-lists' but returns nil instead of signaling errors. +(defmacro c-safe-scan-lists (from count depth &optional limit) + "Like `scan-lists' but returns nil instead of signalling errors +for unbalanced parens. -This function does not do any hidden buffer changes." - (if (featurep 'xemacs) - `(scan-lists ,from ,count ,depth nil t) - `(c-safe (scan-lists ,from ,count ,depth)))) +A limit for the search may be given. FROM is assumed to be on the +right side of it." + (let ((res (if (featurep 'xemacs) + `(scan-lists ,from ,count ,depth nil t) + `(c-safe (scan-lists ,from ,count ,depth))))) + (if limit + `(save-restriction + ,(if (numberp count) + (if (< count 0) + `(narrow-to-region ,limit (point-max)) + `(narrow-to-region (point-min) ,limit)) + `(if (< ,count 0) + (narrow-to-region ,limit (point-max)) + (narrow-to-region (point-min) ,limit))) + ,res) + res))) ;; Wrappers for common scan-lists cases, mainly because it's almost ;; impossible to get a feel for how that function works. -(defmacro c-up-list-forward (&optional pos) +(defmacro c-up-list-forward (&optional pos limit) "Return the first position after the list sexp containing POS, or nil if no such position exists. The point is used if POS is left out. -This function does not do any hidden buffer changes." - `(c-safe-scan-lists ,(or pos `(point)) 1 1)) +A limit for the search may be given. The start position is assumed to +be before it." + `(c-safe-scan-lists ,(or pos `(point)) 1 1 ,limit)) -(defmacro c-up-list-backward (&optional pos) +(defmacro c-up-list-backward (&optional pos limit) "Return the position of the start of the list sexp containing POS, or nil if no such position exists. The point is used if POS is left out. -This function does not do any hidden buffer changes." - `(c-safe-scan-lists ,(or pos `(point)) -1 1)) +A limit for the search may be given. The start position is assumed to +be after it." + `(c-safe-scan-lists ,(or pos `(point)) -1 1 ,limit)) -(defmacro c-down-list-forward (&optional pos) +(defmacro c-down-list-forward (&optional pos limit) "Return the first position inside the first list sexp after POS, or nil if no such position exists. The point is used if POS is left out. -This function does not do any hidden buffer changes." - `(c-safe-scan-lists ,(or pos `(point)) 1 -1)) +A limit for the search may be given. The start position is assumed to +be before it." + `(c-safe-scan-lists ,(or pos `(point)) 1 -1 ,limit)) -(defmacro c-down-list-backward (&optional pos) +(defmacro c-down-list-backward (&optional pos limit) "Return the last position inside the last list sexp before POS, or nil if no such position exists. The point is used if POS is left out. -This function does not do any hidden buffer changes." - `(c-safe-scan-lists ,(or pos `(point)) -1 -1)) +A limit for the search may be given. The start position is assumed to +be after it." + `(c-safe-scan-lists ,(or pos `(point)) -1 -1 ,limit)) -(defmacro c-go-up-list-forward (&optional pos) +(defmacro c-go-up-list-forward (&optional pos limit) "Move the point to the first position after the list sexp containing POS, -or the point if POS is left out. Return t if such a position exists, -otherwise nil is returned and the point isn't moved. +or containing the point if POS is left out. Return t if such a +position exists, otherwise nil is returned and the point isn't moved. -This function does not do any hidden buffer changes." - `(c-safe (goto-char (scan-lists ,(or pos `(point)) 1 1)) t)) +A limit for the search may be given. The start position is assumed to +be before it." + (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) 1 1)) t))) + (if limit + `(save-restriction + (narrow-to-region (point-min) ,limit) + ,res) + res))) -(defmacro c-go-up-list-backward (&optional pos) +(defmacro c-go-up-list-backward (&optional pos limit) "Move the point to the position of the start of the list sexp containing POS, -or the point if POS is left out. Return t if such a position exists, -otherwise nil is returned and the point isn't moved. +or containing the point if POS is left out. Return t if such a +position exists, otherwise nil is returned and the point isn't moved. -This function does not do any hidden buffer changes." - `(c-safe (goto-char (scan-lists ,(or pos `(point)) -1 1)) t)) +A limit for the search may be given. The start position is assumed to +be after it." + (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) -1 1)) t))) + (if limit + `(save-restriction + (narrow-to-region ,limit (point-max)) + ,res) + res))) -(defmacro c-go-down-list-forward (&optional pos) +(defmacro c-go-down-list-forward (&optional pos limit) "Move the point to the first position inside the first list sexp after POS, -or the point if POS is left out. Return t if such a position exists, -otherwise nil is returned and the point isn't moved. +or before the point if POS is left out. Return t if such a position +exists, otherwise nil is returned and the point isn't moved. -This function does not do any hidden buffer changes." - `(c-safe (goto-char (scan-lists ,(or pos `(point)) 1 -1)) t)) +A limit for the search may be given. The start position is assumed to +be before it." + (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) 1 -1)) t))) + (if limit + `(save-restriction + (narrow-to-region (point-min) ,limit) + ,res) + res))) -(defmacro c-go-down-list-backward (&optional pos) +(defmacro c-go-down-list-backward (&optional pos limit) "Move the point to the last position inside the last list sexp before POS, -or the point if POS is left out. Return t if such a position exists, -otherwise nil is returned and the point isn't moved. +or before the point if POS is left out. Return t if such a position +exists, otherwise nil is returned and the point isn't moved. -This function does not do any hidden buffer changes." - `(c-safe (goto-char (scan-lists ,(or pos `(point)) -1 -1)) t)) +A limit for the search may be given. The start position is assumed to +be after it." + (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) -1 -1)) t))) + (if limit + `(save-restriction + (narrow-to-region ,limit (point-max)) + ,res) + res))) (defmacro c-beginning-of-defun-1 () @@ -501,8 +675,6 @@ ;; This is really a bit too large to be a macro but that isn't a ;; problem as long as it only is used in one place in ;; `c-parse-state'. - ;; - ;; This function does not do any hidden buffer changes. `(progn (if (and ,(cc-bytecomp-fboundp 'buffer-syntactic-context-depth) @@ -542,31 +714,84 @@ (looking-at defun-prompt-regexp) (goto-char (match-end 0))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; V i r t u a l S e m i c o l o n s +;; +;; In most CC Mode languages, statements are terminated explicitly by +;; semicolons or closing braces. In some of the CC modes (currently only AWK +;; Mode (April 2004)), statements are (or can be) terminated by EOLs. Such a +;; statement is said to be terminated by a "virtual semicolon" (VS). A +;; statement terminated by an actual semicolon or brace is never considered to +;; have a VS. +;; +;; The indentation engine (or whatever) tests for a VS at a specific position +;; by invoking the macro `c-at-vsemi-p', which in its turn calls the mode +;; specific function (if any) which is the value of the language variable +;; `c-at-vsemi-p-fn'. The actual details of what constitutes a VS in a +;; language are thus encapsulated in code specific to that language +;; (e.g. cc-awk.el). `c-at-vsemi-p' returns non-nil if point (or the optional +;; parameter POS) is at a VS, nil otherwise. +;; +;; The language specific function might well do extensive analysis of the +;; source text, and may use a cacheing scheme to speed up repeated calls. +;; +;; The "virtual semicolon" lies just after the last non-ws token on the line. +;; Like POINT, it is considered to lie between two characters. For example, +;; at the place shown in the following AWK source line: +;; +;; kbyte = 1024 # 1000 if you're not picky +;; ^ +;; | +;; Virtual Semicolon +;; +;; In addition to `c-at-vsemi-p-fn', a mode may need to supply a function for +;; `c-vsemi-status-unknown-p-fn'. The macro `c-vsemi-status-unknown-p' is a +;; rather recondite kludge. It exists because the function +;; `c-beginning-of-statement-1' sometimes tests for VSs as an optimisation, +;; but `c-at-vsemi-p' might well need to call `c-beginning-of-statement-1' in +;; its calculations, thus potentially leading to infinite recursion. +;; +;; The macro `c-vsemi-status-unknown-p' resolves this problem; it may return +;; non-nil at any time; returning nil is a guarantee that an immediate +;; invocation of `c-at-vsemi-p' at point will NOT call +;; `c-beginning-of-statement-1'. `c-vsemi-status-unknown-p' may not itself +;; call `c-beginning-of-statement-1'. +;; +;; The macro `c-vsemi-status-unknown-p' will typically check the cacheing +;; scheme used by the `c-at-vsemp-p-fn', hence the name - the status is +;; "unknown" if there is no cache entry current for the line. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defmacro c-at-vsemi-p (&optional pos) + ;; Is there a virtual semicolon (not a real one or a }) at POS (defaults to + ;; point)? Always returns nil for languages which don't have Virtual + ;; semicolons. + ;; This macro might do hidden buffer changes. + `(if c-at-vsemi-p-fn + (funcall c-at-vsemi-p-fn ,@(if pos `(,pos))))) + +(defmacro c-vsemi-status-unknown-p () + ;; Return NIL only if it can be guaranteed that an immediate + ;; (c-at-vsemi-p) will NOT call c-beginning-of-statement-1. Otherwise, + ;; return non-nil. (See comments above). The function invoked by this + ;; macro MUST NOT UNDER ANY CIRCUMSTANCES itself call + ;; c-beginning-of-statement-1. + ;; Languages which don't have EOL terminated statements always return NIL + ;; (they _know_ there's no vsemi ;-). + `(if c-vsemi-status-unknown-p-fn (funcall c-vsemi-status-unknown-p-fn))) + + (defmacro c-benign-error (format &rest args) ;; Formats an error message for the echo area and dings, i.e. like ;; `error' but doesn't abort. - ;; - ;; This function does not do any hidden buffer changes. `(progn (message ,format ,@args) (ding))) -(defmacro c-update-modeline () - ;; set the c-auto-hungry-string for the correct designation on the modeline - ;; - ;; This function does not do any hidden buffer changes. - `(progn - (setq c-auto-hungry-string - (if c-auto-newline - (if c-hungry-delete-key "/ah" "/a") - (if c-hungry-delete-key "/h" nil))) - (force-mode-line-update))) - (defmacro c-with-syntax-table (table &rest code) ;; Temporarily switches to the specified syntax table in a failsafe ;; way to execute code. - ;; - ;; This function does not do any hidden buffer changes. `(let ((c-with-syntax-table-orig-table (syntax-table))) (unwind-protect (progn @@ -578,9 +803,7 @@ (defmacro c-skip-ws-forward (&optional limit) "Skip over any whitespace following point. This function skips over horizontal and vertical whitespace and line -continuations. - -This function does not do any hidden buffer changes." +continuations." (if limit `(let ((limit (or ,limit (point-max)))) (while (progn @@ -601,9 +824,7 @@ (defmacro c-skip-ws-backward (&optional limit) "Skip over any whitespace preceding point. This function skips over horizontal and vertical whitespace and line -continuations. - -This function does not do any hidden buffer changes." +continuations." (if limit `(let ((limit (or ,limit (point-min)))) (while (progn @@ -624,9 +845,7 @@ (defmacro c-major-mode-is (mode) "Return non-nil if the current CC Mode major mode is MODE. -MODE is either a mode symbol or a list of mode symbols. - -This function does not do any hidden buffer changes." +MODE is either a mode symbol or a list of mode symbols." (if c-langs-are-parametric ;; Inside a `c-lang-defconst'. @@ -643,28 +862,9 @@ (memq c-buffer-is-cc-mode mode) (eq c-buffer-is-cc-mode mode)))))) -(defmacro c-mode-is-new-awk-p () - ;; Is the current mode the "new" awk mode? It is important for - ;; (e.g.) the cc-engine functions do distinguish between the old and - ;; new awk-modes. - '(and (c-major-mode-is 'awk-mode) - (memq 'syntax-properties c-emacs-features))) - -(defmacro c-parse-sexp-lookup-properties () - ;; Return the value of the variable that says whether the - ;; syntax-table property affects the sexp routines. Always return - ;; nil in (X)Emacsen without support for that. - ;; - ;; This function does not do any hidden buffer changes. - (cond ((cc-bytecomp-boundp 'parse-sexp-lookup-properties) - `parse-sexp-lookup-properties) - ((cc-bytecomp-boundp 'lookup-syntax-properties) - `lookup-syntax-properties) - (t nil))) - ;; Macros/functions to handle so-called "char properties", which are -;; properties set on a single character and that never spreads to any +;; properties set on a single character and that never spread to any ;; other characters. (eval-and-compile @@ -719,6 +919,8 @@ ;; ;; If there's a `text-property-default-nonsticky' variable (Emacs ;; 21) then it's assumed that the property is present on it. + ;; + ;; This macro does a hidden buffer change. (setq property (eval property)) (if (or c-use-extents (not (cc-bytecomp-boundp 'text-property-default-nonsticky))) @@ -761,6 +963,8 @@ ;; Remove the given property on the character at POS if it's been put ;; there by `c-put-char-property'. PROPERTY is assumed to be ;; constant. + ;; + ;; This macro does a hidden buffer change. (setq property (eval property)) (cond (c-use-extents ;; XEmacs. @@ -785,6 +989,8 @@ ;; lists of the `rear-nonsticky' properties in the region, if such ;; are used. Thus it should not be used for common properties like ;; `syntax-table'. + ;; + ;; This macro does hidden buffer changes. (setq property (eval property)) (if c-use-extents ;; XEmacs. @@ -795,12 +1001,44 @@ `(remove-text-properties ,from ,to '(,property nil)))) +;; Macros to put overlays (Emacs) or extents (XEmacs) on buffer text. +;; For our purposes, these are characterized by being possible to +;; remove again without affecting the other text properties in the +;; buffer that got overridden when they were put. + +(defmacro c-put-overlay (from to property value) + ;; Put an overlay/extent covering the given range in the current + ;; buffer. It's currently undefined whether it's front/end sticky + ;; or not. The overlay/extent object is returned. + (if (cc-bytecomp-fboundp 'make-overlay) + ;; Emacs. + `(let ((ol (make-overlay ,from ,to))) + (overlay-put ol ,property ,value) + ol) + ;; XEmacs. + `(let ((ext (make-extent ,from ,to))) + (set-extent-property ext ,property ,value) + ext))) + +(defmacro c-delete-overlay (overlay) + ;; Deletes an overlay/extent object previously retrieved using + ;; `c-put-overlay'. + (if (cc-bytecomp-fboundp 'make-overlay) + ;; Emacs. + `(delete-overlay ,overlay) + ;; XEmacs. + `(delete-extent ,overlay))) + + ;; Make edebug understand the macros. (eval-after-load "edebug" '(progn + (def-edebug-spec cc-eval-when-compile t) (def-edebug-spec c-point t) + (def-edebug-spec c-set-region-active t) (def-edebug-spec c-safe t) (def-edebug-spec c-save-buffer-state let*) + (def-edebug-spec c-tentative-buffer-changes t) (def-edebug-spec c-forward-syntactic-ws t) (def-edebug-spec c-backward-syntactic-ws t) (def-edebug-spec c-forward-sexp t) @@ -820,7 +1058,8 @@ (def-edebug-spec c-get-char-property t) (def-edebug-spec c-clear-char-property t) (def-edebug-spec c-clear-char-properties t) - (def-edebug-spec cc-eval-when-compile t))) + (def-edebug-spec c-put-overlay t) + (def-edebug-spec c-delete-overlay t))) ;;; Functions. @@ -847,25 +1086,23 @@ (defsubst c-mark-<-as-paren (pos) ;; Mark the "<" character at POS as an sexp list opener using the - ;; syntax-table property. Note that Emacs 19 and XEmacs <= 20 - ;; doesn't support syntax properties, so this function might not - ;; have any effect. + ;; syntax-table property. + ;; + ;; This function does a hidden buffer change. (c-put-char-property pos 'syntax-table c-<-as-paren-syntax)) (defconst c->-as-paren-syntax '(5 . ?<)) (defsubst c-mark->-as-paren (pos) ;; Mark the ">" character at POS as an sexp list closer using the - ;; syntax-table property. Note that Emacs 19 and XEmacs <= 20 - ;; doesn't support syntax properties, so this function might not - ;; have any effect. + ;; syntax-table property. + ;; + ;; This function does a hidden buffer change. (c-put-char-property pos 'syntax-table c->-as-paren-syntax)) (defsubst c-intersect-lists (list alist) ;; return the element of ALIST that matches the first element found ;; in LIST. Uses assq. - ;; - ;; This function does not do any hidden buffer changes. (let (match) (while (and list (not (setq match (assq (car list) alist)))) @@ -875,41 +1112,33 @@ (defsubst c-lookup-lists (list alist1 alist2) ;; first, find the first entry from LIST that is present in ALIST1, ;; then find the entry in ALIST2 for that entry. - ;; - ;; This function does not do any hidden buffer changes. (assq (car (c-intersect-lists list alist1)) alist2)) (defsubst c-langelem-sym (langelem) "Return the syntactic symbol in LANGELEM. -LANGELEM is a syntactic element, i.e. either a cons cell on the -\"old\" form given as the first argument to lineup functions or a list -on the \"new\" form as used in `c-syntactic-element'. - -This function does not do any hidden buffer changes." +LANGELEM is either a cons cell on the \"old\" form given as the first +argument to lineup functions or a syntactic element on the \"new\" +form as used in `c-syntactic-element'." (car langelem)) (defsubst c-langelem-pos (langelem) - "Return the (primary) anchor position in LANGELEM, or nil if there is none. + "Return the anchor position in LANGELEM, or nil if there is none. -LANGELEM is a syntactic element, i.e. either a cons cell on the -\"old\" form given as the first argument to lineup functions or a list -on the \"new\" form as used in `c-syntactic-element'. - -This function does not do any hidden buffer changes." +LANGELEM is either a cons cell on the \"old\" form given as the first +argument to lineup functions or a syntactic element on the \"new\" +form as used in `c-syntactic-element'." (if (consp (cdr langelem)) (car-safe (cdr langelem)) (cdr langelem))) (defun c-langelem-col (langelem &optional preserve-point) - "Return the column of the (primary) anchor position in LANGELEM. -Leave point at that position unless PRESERVE-POINT is non-nil. + "Return the column of the anchor position in LANGELEM. +Also move the point to that position unless PRESERVE-POINT is non-nil. -LANGELEM is a syntactic element, i.e. either a cons cell on the -\"old\" form given as the first argument to lineup functions or a list -on the \"new\" form as used in `c-syntactic-element'. - -This function does not do any hidden buffer changes." +LANGELEM is either a cons cell on the \"old\" form given as the first +argument to lineup functions or a syntactic element on the \"new\" +form as used in `c-syntactic-element'." (let ((pos (c-langelem-pos langelem)) (here (point))) (if pos @@ -923,38 +1152,18 @@ (defsubst c-langelem-2nd-pos (langelem) "Return the secondary position in LANGELEM, or nil if there is none. -LANGELEM is a syntactic element, typically on the \"new\" form as used -in `c-syntactic-element'. It may be on the \"old\" form that is used -as the first argument to lineup functions, but then the returned value -always will be nil. - -This function does not do any hidden buffer changes." +LANGELEM is typically a syntactic element on the \"new\" form as used +in `c-syntactic-element'. It may also be a cons cell as passed in the +first argument to lineup functions, but then the returned value always +will be nil." (car-safe (cdr-safe (cdr-safe langelem)))) (defsubst c-keep-region-active () ;; Do whatever is necessary to keep the region active in XEmacs. ;; This is not needed for Emacs. - ;; - ;; This function does not do any hidden buffer changes. (and (boundp 'zmacs-region-stays) (setq zmacs-region-stays t))) -(defsubst c-region-is-active-p () - ;; Return t when the region is active. The determination of region - ;; activeness is different in both Emacs and XEmacs. - ;; - ;; This function does not do any hidden buffer changes. - (cond - ;; XEmacs - ((and (fboundp 'region-active-p) - (boundp 'zmacs-regions) - zmacs-regions) - (region-active-p)) - ;; Emacs - ((boundp 'mark-active) mark-active) - ;; fallback; shouldn't get here - (t (mark t)))) - (put 'c-mode 'c-mode-prefix "c-") (put 'c++-mode 'c-mode-prefix "c++-") (put 'objc-mode 'c-mode-prefix "objc-") @@ -965,9 +1174,7 @@ (defsubst c-mode-symbol (suffix) "Prefix the current mode prefix (e.g. \"c-\") to SUFFIX and return -the corresponding symbol. - -This function does not do any hidden buffer changes." +the corresponding symbol." (or c-buffer-is-cc-mode (error "Not inside a CC Mode based mode")) (let ((mode-prefix (get c-buffer-is-cc-mode 'c-mode-prefix))) @@ -978,16 +1185,12 @@ (defsubst c-mode-var (suffix) "Prefix the current mode prefix (e.g. \"c-\") to SUFFIX and return -the value of the variable with that name. - -This function does not do any hidden buffer changes." +the value of the variable with that name." (symbol-value (c-mode-symbol suffix))) (defsubst c-got-face-at (pos faces) "Return non-nil if position POS in the current buffer has any of the -faces in the list FACES. - -This function does not do any hidden buffer changes." +faces in the list FACES." (let ((pos-faces (get-text-property pos 'face))) (if (consp pos-faces) (progn @@ -1003,31 +1206,72 @@ ;; face objects (while it's only their names that are used just ;; about anywhere else) without providing a predicate that tests ;; face names. - ;; - ;; This function does not do any hidden buffer changes. (memq facename (face-list))) +(defun c-concat-separated (list separator) + "Like `concat' on LIST, but separate each element with SEPARATOR. +Notably, null elements in LIST are ignored." + (mapconcat 'identity (delete nil (append list nil)) separator)) + (defun c-make-keywords-re (adorn list &optional mode) "Make a regexp that matches all the strings the list. -Duplicates in the list are removed. The resulting regexp may contain -zero or more submatch expressions. +Duplicates and nil elements in the list are removed. The resulting +regexp may contain zero or more submatch expressions. + +If ADORN is t there will be at least one submatch and the first +surrounds the matched alternative, and the regexp will also not match +a prefix of any identifier. Adorned regexps cannot be appended. The +language variable `c-nonsymbol-key' is used to make the adornment. -If ADORN is non-nil there will be at least one submatch and the first -matches the whole keyword, and the regexp will also not match a prefix -of any identifier. Adorned regexps cannot be appended. The language -variable `c-nonsymbol-key' is used to make the adornment. The -optional MODE specifies the language to get it in. The default is the -current language (taken from `c-buffer-is-cc-mode')." +A value 'appendable for ADORN is like above, but all alternatives in +the list that end with a word constituent char will have \\> appended +instead, so that the regexp remains appendable. Note that this +variant doesn't always guarantee that an identifier prefix isn't +matched since the symbol constituent '_' is normally considered a +nonword token by \\>. + +The optional MODE specifies the language to get `c-nonsymbol-key' from +when it's needed. The default is the current language taken from +`c-buffer-is-cc-mode'." (let (unique) (dolist (elt list) (unless (member elt unique) (push elt unique))) - (setq list unique)) + (setq list (delete nil unique))) (if list - (let ((re (c-regexp-opt list))) + (let (re) - ;; Emacs < 21 and XEmacs (all versions so far) has a buggy + (if (eq adorn 'appendable) + ;; This is kludgy but it works: Search for a string that + ;; doesn't occur in any word in LIST. Append it to all + ;; the alternatives where we want to add \>. Run through + ;; `regexp-opt' and then replace it with \>. + (let ((unique "") pos) + (while (let (found) + (setq unique (concat unique "@") + pos list) + (while (and pos + (if (string-match unique (car pos)) + (progn (setq found t) + nil) + t)) + (setq pos (cdr pos))) + found)) + (setq pos list) + (while pos + (if (string-match "\\w\\'" (car pos)) + (setcar pos (concat (car pos) unique))) + (setq pos (cdr pos))) + (setq re (regexp-opt list)) + (setq pos 0) + (while (string-match unique re pos) + (setq pos (+ (match-beginning 0) 2) + re (replace-match "\\>" t t re)))) + + (setq re (regexp-opt list))) + + ;; Emacs 20 and XEmacs (all versions so far) has a buggy ;; regexp-opt that doesn't always cope with strings containing ;; newlines. This kludge doesn't handle shy parens correctly ;; so we can't advice regexp-opt directly with it. @@ -1041,21 +1285,31 @@ (when fail-list (setq re (concat re "\\|" - (mapconcat 'regexp-quote - (sort fail-list - (lambda (a b) - (> (length a) (length b)))) - "\\|"))))) + (mapconcat + (if (eq adorn 'appendable) + (lambda (str) + (if (string-match "\\w\\'" str) + (concat (regexp-quote str) + "\\>") + (regexp-quote str))) + 'regexp-quote) + (sort fail-list + (lambda (a b) + (> (length a) (length b)))) + "\\|"))))) ;; Add our own grouping parenthesis around re instead of ;; passing adorn to `regexp-opt', since in XEmacs it makes the ;; top level grouping "shy". - (if adorn - (concat "\\(" re "\\)" - "\\(" - (c-get-lang-constant 'c-nonsymbol-key nil mode) - "\\|$\\)") - re)) + (cond ((eq adorn 'appendable) + (concat "\\(" re "\\)")) + (adorn + (concat "\\(" re "\\)" + "\\(" + (c-get-lang-constant 'c-nonsymbol-key nil mode) + "\\|$\\)")) + (t + re))) ;; Produce a regexp that matches nothing. (if adorn @@ -1064,6 +1318,35 @@ (put 'c-make-keywords-re 'lisp-indent-function 1) +(defun c-make-bare-char-alt (chars &optional inverted) + "Make a character alternative string from the list of characters CHARS. +The returned string is of the type that can be used with +`skip-chars-forward' and `skip-chars-backward'. If INVERTED is +non-nil, a caret is prepended to invert the set." + ;; This function ought to be in the elisp core somewhere. + (let ((str (if inverted "^" "")) char char2) + (setq chars (sort (append chars nil) `<)) + (while chars + (setq char (pop chars)) + (if (memq char '(?\\ ?^ ?-)) + ;; Quoting necessary (this method only works in the skip + ;; functions). + (setq str (format "%s\\%c" str char)) + (setq str (format "%s%c" str char))) + ;; Check for range. + (setq char2 char) + (while (and chars (>= (1+ char2) (car chars))) + (setq char2 (pop chars))) + (unless (= char char2) + (if (< (1+ char) char2) + (setq str (format "%s-%c" str char2)) + (push char2 chars)))) + str)) + +;; Leftovers from (X)Emacs 19 compatibility. +(defalias 'c-regexp-opt 'regexp-opt) +(defalias 'c-regexp-opt-depth 'regexp-opt-depth) + ;; Figure out what features this Emacs has @@ -1076,24 +1359,21 @@ ;; I've no idea what this actually is, but it's legacy. /mast (setq list (cons 'infodock list))) - ;; XEmacs 19 and beyond use 8-bit modify-syntax-entry flags. - ;; Emacs 19 uses a 1-bit flag. We will have to set up our + ;; XEmacs uses 8-bit modify-syntax-entry flags. + ;; Emacs uses a 1-bit flag. We will have to set up our ;; syntax tables differently to handle this. (let ((table (copy-syntax-table)) entry) (modify-syntax-entry ?a ". 12345678" table) (cond - ;; XEmacs 19, and beyond Emacs 19.34 + ;; Emacs ((arrayp table) (setq entry (aref table ?a)) ;; In Emacs, table entries are cons cells (if (consp entry) (setq entry (car entry)))) - ;; XEmacs 20 - ((fboundp 'get-char-table) (setq entry (get-char-table ?a table))) - ;; before and including Emacs 19.34 - ((and (fboundp 'char-table-p) - (char-table-p table)) - (setq entry (car (char-table-range table [?a])))) + ;; XEmacs + ((fboundp 'get-char-table) + (setq entry (get-char-table ?a table))) ;; incompatible (t (error "CC Mode is incompatible with this version of Emacs"))) (setq list (cons (if (= (logand (lsh entry -16) 255) 255) @@ -1120,12 +1400,16 @@ (modify-syntax-entry ?< ".") (modify-syntax-entry ?> ".") (insert "<()>") - (c-mark-<-as-paren 1) - (c-mark->-as-paren 4) - (goto-char 1) + (c-mark-<-as-paren (point-min)) + (c-mark->-as-paren (+ 3 (point-min))) + (goto-char (point-min)) (c-forward-sexp) - (if (= (point) 5) - (setq list (cons 'syntax-properties list))) + (if (= (point) (+ 4 (point-min))) + (setq list (cons 'syntax-properties list)) + (error (concat + "CC Mode is incompatible with this version of Emacs - " + "support for the `syntax-table' text property " + "is required."))) ;; Find out if generic comment delimiters work. (c-safe @@ -1153,7 +1437,7 @@ (setq list (cons 'posix-char-classes list))) ;; See if `open-paren-in-column-0-is-defun-start' exists and - ;; isn't buggy. + ;; isn't buggy (Emacs >= 21.4). (when (boundp 'open-paren-in-column-0-is-defun-start) (let ((open-paren-in-column-0-is-defun-start nil) (parse-sexp-ignore-comments t)) @@ -1180,8 +1464,11 @@ (kill-buffer buf)) ;; See if `parse-partial-sexp' returns the eighth element. - (when (c-safe (>= (length (save-excursion (parse-partial-sexp 1 1))) 10)) - (setq list (cons 'pps-extended-state list))) + (if (c-safe (>= (length (save-excursion (parse-partial-sexp 1 1))) 10)) + (setq list (cons 'pps-extended-state list)) + (error (concat + "CC Mode is incompatible with this version of Emacs - " + "`parse-partial-sexp' has to return at least 10 elements."))) ;;(message "c-emacs-features: %S" list) list) @@ -1193,14 +1480,17 @@ '8-bit 8 bit syntax entry flags (XEmacs style). '1-bit 1 bit syntax entry flags (Emacs style). 'syntax-properties It works to override the syntax for specific characters - in the buffer with the 'syntax-table property. + in the buffer with the 'syntax-table property. It's + always set - CC Mode no longer works in emacsen without + this feature. 'gen-comment-delim Generic comment delimiters work (i.e. the syntax class `!'). 'gen-string-delim Generic string delimiters work (i.e. the syntax class `|'). 'pps-extended-state `parse-partial-sexp' returns a list with at least 10 - elements, i.e. it contains the position of the - start of the last comment or string. + elements, i.e. it contains the position of the start of + the last comment or string. It's always set - CC Mode no + longer works in emacsen without this feature. 'posix-char-classes The regexp engine understands POSIX character classes. 'col-0-paren It's possible to turn off the ad-hoc rule that a paren in column zero is the start of a defun. @@ -1359,9 +1649,7 @@ one `c-lang-defconst' for each NAME is permitted per file. If there already is one it will be completely replaced; the value in the earlier definition will not affect `c-lang-const' on the same -constant. A file is identified by its base name. - -This macro does not do any hidden buffer changes." +constant. A file is identified by its base name." (let* ((sym (intern (symbol-name name) c-lang-constants)) ;; Make `c-lang-const' expand to a straightforward call to @@ -1451,8 +1739,7 @@ (&define name [&optional stringp] [&rest sexp def-form]))) (defun c-define-lang-constant (name bindings &optional pre-files) - ;; Used by `c-lang-defconst'. This function does not do any hidden - ;; buffer changes. + ;; Used by `c-lang-defconst'. (let* ((sym (intern (symbol-name name) c-lang-constants)) (source (get sym 'source)) @@ -1504,9 +1791,7 @@ \"-mode\" suffix. If used inside `c-lang-defconst' or `c-lang-defvar', LANG may be left out to refer to the current language. NAME and LANG are not evaluated so they should not be -quoted. - -This macro does not do any hidden buffer changes." +quoted." (or (symbolp name) (error "Not a symbol: %s" name)) @@ -1516,18 +1801,12 @@ (let ((sym (intern (symbol-name name) c-lang-constants)) mode source-files args) - (if lang - (progn - (setq mode (intern (concat (symbol-name lang) "-mode"))) - (unless (get mode 'c-mode-prefix) - (error - "Unknown language %S since it got no `c-mode-prefix' property" - (symbol-name lang)))) - (if c-buffer-is-cc-mode - (setq lang c-buffer-is-cc-mode) - (or c-langs-are-parametric - (error - "`c-lang-const' requires a literal language in this context")))) + (when lang + (setq mode (intern (concat (symbol-name lang) "-mode"))) + (unless (get mode 'c-mode-prefix) + (error + "Unknown language %S since it got no `c-mode-prefix' property" + (symbol-name lang)))) (if (eq c-lang-const-expansion 'immediate) ;; No need to find out the source file(s) when we evaluate @@ -1550,7 +1829,7 @@ (list (car elem)))) (get sym 'source)))))) - ;; Spend some effort to make a compact call to + ;; Make some effort to do a compact call to ;; `c-get-lang-constant' since it will be compiled in. (setq args (and mode `(',mode))) (if (or source-files args) @@ -1558,12 +1837,15 @@ args))) (if (or (eq c-lang-const-expansion 'call) + (and (not c-lang-const-expansion) + (not mode)) load-in-progress (not (boundp 'byte-compile-dest-file)) (not (stringp byte-compile-dest-file))) ;; Either a straight call is requested in the context, or - ;; we're not being byte compiled so the compile time stuff - ;; below is unnecessary. + ;; we're in an "uncontrolled" context and got no language, + ;; or we're not being byte compiled so the compile time + ;; stuff below is unnecessary. `(c-get-lang-constant ',name ,@args) ;; Being compiled. If the loading and compiling version is @@ -1577,8 +1859,7 @@ (defvar c-lang-constants-under-evaluation nil) (defun c-get-lang-constant (name &optional source-files mode) - ;; Used by `c-lang-const'. This function does not do any hidden - ;; buffer changes. + ;; Used by `c-lang-const'. (or mode (setq mode c-buffer-is-cc-mode) @@ -1755,5 +2036,5 @@ (cc-provide 'cc-defs) -;;; arch-tag: 3bb2629d-dd84-4ff0-ad39-584be0fe3cda +;; arch-tag: 3bb2629d-dd84-4ff0-ad39-584be0fe3cda ;;; cc-defs.el ends here diff -r 8e25aa911e3e -r 37d0562504bf lisp/progmodes/cc-engine.el --- a/lisp/progmodes/cc-engine.el Sat Dec 10 21:12:12 2005 +0000 +++ b/lisp/progmodes/cc-engine.el Sat Dec 10 21:18:28 2005 +0000 @@ -1,6 +1,7 @@ ;;; cc-engine.el --- core syntax guessing engine for CC mode -;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc. +;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, +;; Inc. ;; Authors: 1998- Martin Stjernholm ;; 1992-1999 Barry A. Warsaw @@ -44,21 +45,29 @@ ;; ;; Various functions in CC Mode use text properties for caching and ;; syntactic markup purposes, and those of them that might modify such -;; properties are said to do "hidden buffer changes". They should be -;; used within `c-save-buffer-state' or a similar function that saves -;; and restores buffer modifiedness etc. +;; properties but still don't modify the buffer in a visible way are +;; said to do "hidden buffer changes". They should be used within +;; `c-save-buffer-state' or a similar function that saves and restores +;; buffer modifiedness, disables buffer change hooks, etc. ;; -;; Interactive functions are assumed to not do hidden buffer changes -;; (this isn't applicable in the specific parts of them that do real -;; changes, though). +;; Interactive functions are assumed to not do hidden buffer changes, +;; except in the specific parts of them that do real changes. +;; +;; Lineup functions are assumed to do hidden buffer changes. They +;; must not do real changes, though. ;; -;; All other functions are assumed to do hidden buffer changes and -;; must thus be wrapped inside `c-save-buffer-state' if they're used -;; from any function that does not do hidden buffer changes. +;; All other functions that do hidden buffer changes have that noted +;; in their doc string or comment. ;; -;; Every function, except the interactive ones, that doesn't do hidden -;; buffer changes have that explicitly stated in their docstring or -;; comment. +;; The intention with this system is to avoid wrapping every leaf +;; function that do hidden buffer changes inside +;; `c-save-buffer-state'. It should be used as near the top of the +;; interactive functions as possible. +;; +;; Functions called during font locking are allowed to do hidden +;; buffer changes since the font-lock package run them in a context +;; similar to `c-save-buffer-state' (in fact, that function is heavily +;; inspired by `save-buffer-state' in the font-lock package). ;; Use of text properties ;; @@ -86,8 +95,8 @@ ;; ;; 'c-type ;; This property is used on single characters to mark positions with -;; special syntactic relevance of various sorts. It's primary use -;; is to avoid glitches when multiline constructs are refontified +;; special syntactic relevance of various sorts. Its primary use is +;; to avoid glitches when multiline constructs are refontified ;; interactively (on font lock decoration level 3). It's cleared in ;; a region before it's fontified and is then put on relevant chars ;; in that region as they are encountered during the fontification. @@ -134,19 +143,6 @@ (cc-require-when-compile 'cc-langs) (cc-require 'cc-vars) -;; Some functions/constants in cc-awk.el that are called/referenced here. -;; (Can't use cc-require due to cyclicity.) -(cc-bytecomp-defun c-awk-unstick-NL-prop) -(cc-bytecomp-defun c-awk-clear-NL-props) -(cc-bytecomp-defvar awk-mode-syntax-table) -(cc-bytecomp-defun c-awk-backward-syntactic-ws) -(cc-bytecomp-defun c-awk-after-logical-semicolon) -(cc-bytecomp-defun c-awk-NL-prop-not-set) -(cc-bytecomp-defun c-awk-completed-stmt-ws-ends-line-p) -(cc-bytecomp-defun c-awk-completed-stmt-ws-ends-prev-line-p) -(cc-bytecomp-defun c-awk-prev-line-incomplete-p) -(cc-bytecomp-defun c-awk-after-change) - ;; Silence the compiler. (cc-bytecomp-defun buffer-syntactic-context) ; XEmacs @@ -171,13 +167,20 @@ (defvar c-hungry-delete-key nil) (make-variable-buffer-local 'c-hungry-delete-key) +;; The electric flag (toggled by `c-toggle-electric-state'). +;; If t, electric actions (like automatic reindentation, and (if +;; c-auto-newline is also set) auto newlining) will happen when an electric +;; key like `{' is pressed (or an electric keyword like `else'). +(defvar c-electric-flag t) +(make-variable-buffer-local 'c-electric-flag) + ;; Internal state of auto newline feature. (defvar c-auto-newline nil) (make-variable-buffer-local 'c-auto-newline) -;; Internal auto-newline/hungry-delete designation string for mode line. -(defvar c-auto-hungry-string nil) -(make-variable-buffer-local 'c-auto-hungry-string) +;; Included in the mode line to indicate the active submodes. +(defvar c-submode-indicators nil) +(make-variable-buffer-local 'c-submode-indicators) (defun c-calculate-state (arg prevstate) ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If @@ -191,11 +194,6 @@ ;; Dynamically bound cache for `c-in-literal'. (defvar c-in-literal-cache t) -;; Must be set in buffers where the `c-type' text property might be used -;; with the value `c-decl-end'. -(defvar c-type-decl-end-used nil) -(make-variable-buffer-local 'c-type-decl-end-used) - ;; Basic handling of preprocessor directives. @@ -205,19 +203,19 @@ (defvar c-macro-start 'unknown) (defsubst c-query-and-set-macro-start () - ;; This function does not do any hidden buffer changes. (if (symbolp c-macro-start) (setq c-macro-start (save-excursion - (and (c-beginning-of-macro) - (point)))) + (c-save-buffer-state () + (and (c-beginning-of-macro) + (point))))) c-macro-start)) (defsubst c-query-macro-start () - ;; This function does not do any hidden buffer changes. (if (symbolp c-macro-start) (save-excursion - (and (c-beginning-of-macro) - (point))) + (c-save-buffer-state () + (and (c-beginning-of-macro) + (point)))) c-macro-start)) (defun c-beginning-of-macro (&optional lim) @@ -225,7 +223,8 @@ Leave point at the beginning of the directive and return t if in one, otherwise return nil and leave point unchanged. -This function does not do any hidden buffer changes." +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." (when c-opt-cpp-prefix (let ((here (point))) (save-restriction @@ -242,10 +241,12 @@ (defun c-end-of-macro () "Go to the end of a preprocessor directive. -More accurately, move point to the end of the closest following line -that doesn't end with a line continuation backslash. - -This function does not do any hidden buffer changes." +More accurately, move the point to the end of the closest following +line that doesn't end with a line continuation backslash - no check is +done that the point is inside a cpp directive to begin with. + +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." (while (progn (end-of-line) (when (and (eq (char-before) ?\\) @@ -256,95 +257,81 @@ (defun c-forward-to-cpp-define-body () ;; Assuming point is at the "#" that introduces a preprocessor ;; directive, it's moved forward to the start of the definition body - ;; if it's a "#define". Non-nil is returned in this case, in all - ;; other cases nil is returned and point isn't moved. - (when (and (looking-at - (concat "#[ \t]*" - "define[ \t]+\\(\\sw\\|_\\)+\\(\([^\)]*\)\\)?" - "\\([ \t]\\|\\\\\n\\)*")) + ;; if it's a "#define" (or whatever c-opt-cpp-macro-define + ;; specifies). Non-nil is returned in this case, in all other cases + ;; nil is returned and point isn't moved. + ;; + ;; This function might do hidden buffer changes. + (when (and c-opt-cpp-macro-define-start + (looking-at c-opt-cpp-macro-define-start) (not (= (match-end 0) (c-point 'eol)))) (goto-char (match-end 0)))) ;;; Basic utility functions. -(defun c-syntactic-content (from to) +(defun c-syntactic-content (from to paren-level) ;; Return the given region as a string where all syntactic ;; whitespace is removed or, where necessary, replaced with a single - ;; space. + ;; space. If PAREN-LEVEL is given then all parens in the region are + ;; collapsed to "()", "[]" etc. + ;; + ;; This function might do hidden buffer changes. + (save-excursion - (goto-char from) - (let* ((parts (list nil)) (tail parts) pos) - (while (re-search-forward c-syntactic-ws-start to t) - (goto-char (setq pos (match-beginning 0))) - (c-forward-syntactic-ws to) - (if (= (point) pos) - (forward-char) - (if (and (> pos from) - (< (point) to) - (looking-at "\\w\\|\\s_") - (save-excursion - (goto-char (1- pos)) - (looking-at "\\w\\|\\s_"))) - (progn - (setcdr tail (list (buffer-substring-no-properties from pos) - " ")) - (setq tail (cddr tail))) - (setcdr tail (list (buffer-substring-no-properties from pos))) - (setq tail (cdr tail))) - (setq from (point)))) - (setcdr tail (list (buffer-substring-no-properties from to))) - (apply 'concat (cdr parts))))) - -(defsubst c-keyword-sym (keyword) - ;; Return non-nil if the string KEYWORD is a known keyword. More - ;; precisely, the value is the symbol for the keyword in - ;; `c-keywords-obarray'. - (intern-soft keyword c-keywords-obarray)) - -(defsubst c-keyword-member (keyword-sym lang-constant) - ;; Return non-nil if the symbol KEYWORD-SYM, as returned by - ;; `c-keyword-sym', is a member of LANG-CONSTANT, which is the name - ;; of a language constant that ends with "-kwds". If KEYWORD-SYM is - ;; nil then the result is nil. - (get keyword-sym lang-constant)) - -;; String syntax chars, suitable for skip-syntax-(forward|backward). -(defconst c-string-syntax (if (memq 'gen-string-delim c-emacs-features) - "\"|" - "\"")) - -;; Regexp matching string start syntax. -(defconst c-string-limit-regexp (if (memq 'gen-string-delim c-emacs-features) - "\\s\"\\|\\s|" - "\\s\"")) - -;; Holds formatted error strings for the few cases where parse errors -;; are reported. -(defvar c-parsing-error nil) -(make-variable-buffer-local 'c-parsing-error) - -(defun c-echo-parsing-error (&optional quiet) - ;; This function does not do any hidden buffer changes. - (when (and c-report-syntactic-errors c-parsing-error (not quiet)) - (c-benign-error "%s" c-parsing-error)) - c-parsing-error) - -;; Faces given to comments and string literals. This is used in some -;; situations to speed up recognition; it isn't mandatory that font -;; locking is in use. This variable is extended with the face in -;; `c-doc-face-name' when fontification is activated in cc-fonts.el. -(defvar c-literal-faces - '(font-lock-comment-face font-lock-string-face - font-lock-comment-delimiter-face)) + (save-restriction + (narrow-to-region from to) + (goto-char from) + (let* ((parts (list nil)) (tail parts) pos in-paren) + + (while (re-search-forward c-syntactic-ws-start to t) + (goto-char (setq pos (match-beginning 0))) + (c-forward-syntactic-ws) + (if (= (point) pos) + (forward-char) + + (when paren-level + (save-excursion + (setq in-paren (= (car (parse-partial-sexp from pos 1)) 1) + pos (point)))) + + (if (and (> pos from) + (< (point) to) + (looking-at "\\w\\|\\s_") + (save-excursion + (goto-char (1- pos)) + (looking-at "\\w\\|\\s_"))) + (progn + (setcdr tail (list (buffer-substring-no-properties from pos) + " ")) + (setq tail (cddr tail))) + (setcdr tail (list (buffer-substring-no-properties from pos))) + (setq tail (cdr tail))) + + (when in-paren + (when (= (car (parse-partial-sexp pos to -1)) -1) + (setcdr tail (list (buffer-substring-no-properties + (1- (point)) (point)))) + (setq tail (cdr tail)))) + + (setq from (point)))) + + (setcdr tail (list (buffer-substring-no-properties from to))) + (apply 'concat (cdr parts)))))) (defun c-shift-line-indentation (shift-amt) - ;; This function does not do any hidden buffer changes. + ;; Shift the indentation of the current line with the specified + ;; amount (positive inwards). The buffer is modified only if + ;; SHIFT-AMT isn't equal to zero. (let ((pos (- (point-max) (point))) (c-macro-start c-macro-start) tmp-char-inserted) (if (zerop shift-amt) nil + ;; If we're on an empty line inside a macro, we take the point + ;; to be at the current indentation and shift it to the + ;; appropriate column. This way we don't treat the extra + ;; whitespace out to the line continuation as indentation. (when (and (c-query-and-set-macro-start) (looking-at "[ \t]*\\\\$") (save-excursion @@ -369,6 +356,72 @@ (if (> (- (point-max) pos) (point)) (goto-char (- (point-max) pos)))))) +(defsubst c-keyword-sym (keyword) + ;; Return non-nil if the string KEYWORD is a known keyword. More + ;; precisely, the value is the symbol for the keyword in + ;; `c-keywords-obarray'. + (intern-soft keyword c-keywords-obarray)) + +(defsubst c-keyword-member (keyword-sym lang-constant) + ;; Return non-nil if the symbol KEYWORD-SYM, as returned by + ;; `c-keyword-sym', is a member of LANG-CONSTANT, which is the name + ;; of a language constant that ends with "-kwds". If KEYWORD-SYM is + ;; nil then the result is nil. + (get keyword-sym lang-constant)) + +;; String syntax chars, suitable for skip-syntax-(forward|backward). +(defconst c-string-syntax (if (memq 'gen-string-delim c-emacs-features) + "\"|" + "\"")) + +;; Regexp matching string limit syntax. +(defconst c-string-limit-regexp (if (memq 'gen-string-delim c-emacs-features) + "\\s\"\\|\\s|" + "\\s\"")) + +;; Regexp matching WS followed by string limit syntax. +(defconst c-ws*-string-limit-regexp + (concat "[ \t]*\\(" c-string-limit-regexp "\\)")) + +;; Holds formatted error strings for the few cases where parse errors +;; are reported. +(defvar c-parsing-error nil) +(make-variable-buffer-local 'c-parsing-error) + +(defun c-echo-parsing-error (&optional quiet) + (when (and c-report-syntactic-errors c-parsing-error (not quiet)) + (c-benign-error "%s" c-parsing-error)) + c-parsing-error) + +;; Faces given to comments and string literals. This is used in some +;; situations to speed up recognition; it isn't mandatory that font +;; locking is in use. This variable is extended with the face in +;; `c-doc-face-name' when fontification is activated in cc-fonts.el. +(defvar c-literal-faces + (append '(font-lock-comment-face font-lock-string-face) + (when (facep 'font-lock-comment-delimiter-face) + ;; New in Emacs 22. + '(font-lock-comment-delimiter-face)))) + +(defsubst c-put-c-type-property (pos value) + ;; Put a c-type property with the given value at POS. + (c-put-char-property pos 'c-type value)) + +(defun c-clear-c-type-property (from to value) + ;; Remove all occurences of the c-type property that has the given + ;; value in the region between FROM and TO. VALUE is assumed to not + ;; be nil. + ;; + ;; Note: This assumes that c-type is put on single chars only; it's + ;; very inefficient if matching properties cover large regions. + (save-excursion + (goto-char from) + (while (progn + (when (eq (get-text-property (point) 'c-type) value) + (c-clear-char-property (point) 'c-type)) + (goto-char (next-single-property-change (point) 'c-type nil to)) + (< (point) to))))) + ;; Some debug tools to visualize various special positions. This ;; debug code isn't as portable as the rest of CC Mode. @@ -414,7 +467,7 @@ ;; c-crosses-statement-barrier-p and c-beginning-of-statement-1. A ;; better way should be implemented, but this will at least shut up ;; the byte compiler. -(defvar c-maybe-labelp nil) +(defvar c-maybe-labelp) ;; New awk-compatible version of c-beginning-of-statement-1, ACM 2002/6/22 @@ -470,11 +523,9 @@ move to the closest containing statement if there is any. This might also stop at a continuation clause. -Labels are treated as separate statements if IGNORE-LABELS is non-nil. -The function is not overly intelligent in telling labels from other -uses of colons; if used outside a statement context it might trip up -on e.g. inherit colons, so IGNORE-LABELS should be used then. There -should be no such mistakes in a statement context, however. +Labels are treated as part of the following statements if +IGNORE-LABELS is non-nil. (FIXME: Doesn't work if we stop at a known +statement start keyword.) Macros are ignored unless point is within one, in which case the content of the macro is treated as normal code. Aside from any normal @@ -497,7 +548,10 @@ NOERROR turns off error logging to `c-parsing-error'. Normally only ';' is considered to delimit statements, but if -COMMA-DELIM is non-nil then ',' is treated likewise." +COMMA-DELIM is non-nil then ',' is treated likewise. + +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." ;; The bulk of this function is a pushdown automaton that looks at statement ;; boundaries and the tokens (such as "while") in c-opt-block-stmt-key. Its @@ -587,20 +641,43 @@ (c-stmt-delim-chars (if comma-delim c-stmt-delim-chars-with-comma c-stmt-delim-chars)) - pos ; Current position. - boundary-pos ; Position of last stmt boundary character (e.g. ;). - after-labels-pos ; Value of tok after first found colon. - last-label-pos ; Value of tok after last found colon. - sym ; Symbol just scanned back over (e.g. 'while or - ; 'boundary). See above - state ; Current state in the automaton. See above. - saved-pos ; Current saved positions. See above - stack ; Stack of conses (state . saved-pos). - (cond-key (or c-opt-block-stmt-key ; regexp which matches "for", "if", etc. + c-in-literal-cache c-maybe-labelp saved + ;; Current position. + pos + ;; Position of last stmt boundary character (e.g. ;). + boundary-pos + ;; The position of the last sexp or bound that follows the + ;; first found colon, i.e. the start of the nonlabel part of + ;; the statement. It's `start' if a colon is found just after + ;; the start. + after-labels-pos + ;; Like `after-labels-pos', but the first such position inside + ;; a label, i.e. the start of the last label before the start + ;; of the nonlabel part of the statement. + last-label-pos + ;; The last position where a label is possible provided the + ;; statement started there. It's nil as long as no invalid + ;; label content has been found (according to + ;; `c-nonlabel-token-key'. It's `start' if no valid label + ;; content was found in the label. Note that we might still + ;; regard it a label if it starts with `c-label-kwds'. + label-good-pos + ;; Symbol just scanned back over (e.g. 'while or 'boundary). + ;; See above. + sym + ;; Current state in the automaton. See above. + state + ;; Current saved positions. See above. + saved-pos + ;; Stack of conses (state . saved-pos). + stack + ;; Regexp which matches "for", "if", etc. + (cond-key (or c-opt-block-stmt-key "\\<\\>")) ; Matches nothing. - (ret 'same) ; Return value. - tok ptok pptok ; Pos of last three sexps or bounds. - c-in-literal-cache c-maybe-labelp saved) + ;; Return value. + (ret 'same) + ;; Positions of the last three sexps or bounds we've stopped at. + tok ptok pptok) (save-restriction (if lim (narrow-to-region lim (point-max))) @@ -614,32 +691,23 @@ ;; that we've moved. (while (progn (setq pos (point)) - (if (c-mode-is-new-awk-p) - (c-awk-backward-syntactic-ws) - (c-backward-syntactic-ws)) - (/= (skip-chars-backward "-+!*&~@`#") 0))) ; ACM, 2002/5/31; - ; Make a variable in - ; cc-langs.el, maybe + (c-backward-syntactic-ws) + ;; Protect post-++/-- operators just before a virtual semicolon. + (and (not (c-at-vsemi-p)) + (/= (skip-chars-backward "-+!*&~@`#") 0)))) ;; Skip back over any semicolon here. If it was a bare semicolon, we're - ;; done. Later on we ignore the boundaries for statements that doesn't + ;; done. Later on we ignore the boundaries for statements that don't ;; contain any sexp. The only thing that is affected is that the error ;; checking is a little less strict, and we really don't bother. (if (and (memq (char-before) delims) (progn (forward-char -1) (setq saved (point)) - (if (c-mode-is-new-awk-p) - (c-awk-backward-syntactic-ws) - (c-backward-syntactic-ws)) + (c-backward-syntactic-ws) (or (memq (char-before) delims) (memq (char-before) '(?: nil)) (eq (char-syntax (char-before)) ?\() - (and (c-mode-is-new-awk-p) - (c-awk-after-logical-semicolon))))) ; ACM 2002/6/22 - ;; ACM, 2002/7/20: What about giving a limit to the above function? - ;; ACM, 2003/6/16: The above two lines (checking for - ;; awk-logical-semicolon) are probably redundant after rewriting - ;; c-awk-backward-syntactic-ws. + (c-at-vsemi-p)))) (setq ret 'previous pos saved) @@ -657,11 +725,8 @@ (while (catch 'loop ;; Throw nil to break, non-nil to continue. (cond - ;; Check for macro start. Take this out for AWK Mode (ACM, 2002/5/31) - ;; NO!! just make sure macro-start is nil in AWK Mode (ACM, 2002/6/22) - ;; It always is (ACM, 2002/6/23) ((save-excursion - (and macro-start + (and macro-start ; Always NIL for AWK. (progn (skip-chars-backward " \t") (eq (char-before) ?#)) (progn (setq saved (1- (point))) @@ -767,23 +832,22 @@ (c-bos-save-error-info 'if 'else) (setq state 'else)) ((eq sym 'while) + ;; Is this a real while, or a do-while? + ;; The next `when' triggers unless we are SURE that + ;; the `while' is not the tailend of a `do-while'. (when (or (not pptok) (memq (char-after pptok) delims) - (and (c-mode-is-new-awk-p) - (or - ;; might we be calling this from - ;; c-awk-after-if-do-for-while-condition-p? - ;; If so, avoid infinite recursion. - (and (eq (point) start) - (c-awk-NL-prop-not-set)) - ;; The following may recursively - ;; call this function. - (c-awk-completed-stmt-ws-ends-line-p pptok)))) + ;; The following kludge is to prevent + ;; infinite recursion when called from + ;; c-awk-after-if-for-while-condition-p, + ;; or the like. + (and (eq (point) start) + (c-vsemi-status-unknown-p)) + (c-at-vsemi-p pptok)) ;; Since this can cause backtracking we do a ;; little more careful analysis to avoid it: If - ;; the while isn't followed by a semicolon it - ;; can't be a do-while. - ;; ACM, 2002/5/31; IT CAN IN AWK Mode. ;-( + ;; the while isn't followed by a (possibly + ;; virtual) semicolon it can't be a do-while. (c-bos-push-state) (setq state 'while))) ((memq sym '(catch finally)) @@ -805,80 +869,95 @@ (setq ret 'previous) ;; HERE IS THE SINGLE PLACE INSIDE THE PDA LOOP WHERE WE MOVE - ;; BACKWARDS THROUGH THE SOURCE. The following loop goes back - ;; one sexp and then only loops in special circumstances (line - ;; continuations and skipping past entire macros). - (while - (progn - (or (c-safe (goto-char (scan-sexps (point) -1)) t) - ;; Give up if we hit an unbalanced block. - ;; Since the stack won't be empty the code - ;; below will report a suitable error. + ;; BACKWARDS THROUGH THE SOURCE. + + ;; This is typically fast with the caching done by + ;; c-(backward|forward)-sws. + (c-backward-syntactic-ws) + + (let ((before-sws-pos (point)) + ;; Set as long as we have to continue jumping by sexps. + ;; It's the position to use as end in the next round. + sexp-loop-continue-pos + ;; The end position of the area to search for statement + ;; barriers in this round. + (sexp-loop-end-pos pos)) + + (while + (progn + (unless (c-safe (c-backward-sexp) t) + ;; Give up if we hit an unbalanced block. Since the + ;; stack won't be empty the code below will report a + ;; suitable error. (throw 'loop nil)) - (cond ((looking-at "\\\\$") - ;; Step again if we hit a line continuation. - t) - (macro-start - ;; If we started inside a macro then this - ;; sexp is always interesting. - nil) - ((not (c-mode-is-new-awk-p)) ; Changed from t, ACM 2002/6/25 - ;; Otherwise check that we didn't step - ;; into a macro from the end. - (let ((macro-start - (save-excursion - (and (c-beginning-of-macro) - (point))))) - (when macro-start - (goto-char macro-start) - t)))))) - - ;; Did the last movement by a sexp cross a statement boundary? - (when (save-excursion - (if (if (eq (char-after) ?{) - (c-looking-at-inexpr-block lim nil) - (looking-at "\\s\(")) - - ;; Should not include the paren sexp we've - ;; passed over in the boundary check. - (if (> (point) (- pos 100)) - (c-forward-sexp 1) - - ;; Find its end position this way instead of - ;; moving forward if the sexp is large. - (goto-char pos) - (while - (progn - (goto-char (1+ (c-down-list-backward))) - (unless macro-start - ;; Check that we didn't step into - ;; a macro from the end. - (let ((macro-start - (save-excursion - (and (c-beginning-of-macro) - (point))))) - (when macro-start - (goto-char macro-start) - t))))))) - - (setq boundary-pos (c-crosses-statement-barrier-p - (point) pos))) - - (setq pptok ptok - ptok tok - tok boundary-pos - sym 'boundary) - (throw 'loop t))) ; like a C "continue". Analyze the next sexp. - - (when (and (numberp c-maybe-labelp) - (not ignore-labels) - (not (looking-at "\\s\("))) - ;; c-crosses-statement-barrier-p has found a colon, so - ;; we might be in a label now. - (if (not after-labels-pos) - (setq after-labels-pos tok)) - (setq last-label-pos tok - c-maybe-labelp t)) + + ;; Check if the sexp movement crossed a statement or + ;; declaration boundary. But first modify the point + ;; so that `c-crosses-statement-barrier-p' only looks + ;; at the non-sexp chars following the sexp. + (save-excursion + (when (setq + boundary-pos + (cond + ((if macro-start + nil + (save-excursion + (when (c-beginning-of-macro) + ;; Set continuation position in case + ;; `c-crosses-statement-barrier-p' + ;; doesn't detect anything below. + (setq sexp-loop-continue-pos (point))))) + ;; If the sexp movement took us into a + ;; macro then there were only some non-sexp + ;; chars after it. Skip out of the macro + ;; to analyze them but not the non-sexp + ;; chars that might be inside the macro. + (c-end-of-macro) + (c-crosses-statement-barrier-p + (point) sexp-loop-end-pos)) + + ((and + (eq (char-after) ?{) + (not (c-looking-at-inexpr-block lim nil t))) + ;; Passed a block sexp. That's a boundary + ;; alright. + (point)) + + ((looking-at "\\s\(") + ;; Passed some other paren. Only analyze + ;; the non-sexp chars after it. + (goto-char (1+ (c-down-list-backward + before-sws-pos))) + ;; We're at a valid token start position + ;; (outside the `save-excursion') if + ;; `c-crosses-statement-barrier-p' failed. + (c-crosses-statement-barrier-p + (point) sexp-loop-end-pos)) + + (t + ;; Passed a symbol sexp or line + ;; continuation. It doesn't matter that + ;; it's included in the analyzed region. + (if (c-crosses-statement-barrier-p + (point) sexp-loop-end-pos) + t + ;; If it was a line continuation then we + ;; have to continue looping. + (if (looking-at "\\\\$") + (setq sexp-loop-continue-pos (point))) + nil)))) + + (setq pptok ptok + ptok tok + tok boundary-pos + sym 'boundary) + ;; Like a C "continue". Analyze the next sexp. + (throw 'loop t))) + + sexp-loop-continue-pos) + (goto-char sexp-loop-continue-pos) + (setq sexp-loop-end-pos sexp-loop-continue-pos + sexp-loop-continue-pos nil)))) ;; ObjC method def? (when (and c-opt-method-key @@ -887,7 +966,26 @@ ignore-labels t) ; Avoid the label check on exit. (throw 'loop nil)) - ;; We've moved back by a sexp, so update the token positions. + ;; Handle labels. + (unless (eq ignore-labels t) + (when (numberp c-maybe-labelp) + ;; `c-crosses-statement-barrier-p' has found a + ;; colon, so we might be in a label now. + (if after-labels-pos + (if (not last-label-pos) + (setq last-label-pos (or tok start))) + (setq after-labels-pos (or tok start))) + (setq c-maybe-labelp t + label-good-pos nil)) + + (when (and (not label-good-pos) + (looking-at c-nonlabel-token-key)) + ;; We're in a potential label and it's the first + ;; time we've found something that isn't allowed in + ;; one. + (setq label-good-pos (or tok start)))) + + ;; We've moved back by a sexp, so update the token positions. (setq sym nil pptok ptok ptok tok @@ -911,25 +1009,34 @@ (cond ((> start saved) (setq pos saved)) ((= start saved) (setq ret 'up))))) - (when (and c-maybe-labelp - (not ignore-labels) + (when (and (not ignore-labels) + (eq c-maybe-labelp t) (not (eq ret 'beginning)) - after-labels-pos) + after-labels-pos + (or (not label-good-pos) + (<= label-good-pos pos) + (progn + (goto-char (if (and last-label-pos + (< last-label-pos start)) + last-label-pos + pos)) + (looking-at c-label-kwds-regexp)))) ;; We're in a label. Maybe we should step to the statement ;; after it. (if (< after-labels-pos start) (setq pos after-labels-pos) (setq ret 'label) - (if (< last-label-pos start) + (if (and last-label-pos (< last-label-pos start)) + ;; Might have jumped over several labels. Go to the last one. (setq pos last-label-pos))))) ;; Skip over the unary operators that can start the statement. (goto-char pos) (while (progn - (if (c-mode-is-new-awk-p) - (c-awk-backward-syntactic-ws) - (c-backward-syntactic-ws)) - (/= (skip-chars-backward "-+!*&~@`#") 0)) ; Hopefully the # won't hurt awk. + (c-backward-syntactic-ws) + ;; protect AWK post-inc/decrement operators, etc. + (and (not (c-at-vsemi-p (point))) + (/= (skip-chars-backward "-+!*&~@`#") 0))) (setq pos (point))) (goto-char pos) ret))) @@ -942,7 +1049,14 @@ The variable `c-maybe-labelp' is set to the position of the first `:' that might start a label (i.e. not part of `::' and not preceded by `?'). If a -single `?' is found, then `c-maybe-labelp' is cleared." +single `?' is found, then `c-maybe-labelp' is cleared. + +For AWK, a statement which is terminated by an EOL (not a \; or a }) is +regarded as having a \"virtual semicolon\" immediately after the last token on +the line. If this virtual semicolon is _at_ from, the function recognises it. + +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." (let ((skip-chars c-stmt-delim-chars) lit-range) (save-excursion @@ -950,30 +1064,85 @@ (goto-char from) (while (progn (skip-chars-forward skip-chars to) (< (point) to)) - (if (setq lit-range (c-literal-limits from)) ; Have we landed in a string/comment? - (progn (goto-char (setq from (cdr lit-range))) - (if (and (c-mode-is-new-awk-p) (bolp)) ; ACM 2002/7/17. Make sure we - (backward-char))) ; don't skip over a virtual semi-colon after an awk comment. :-( - (cond ((eq (char-after) ?:) - (forward-char) - (if (and (eq (char-after) ?:) - (< (point) to)) - ;; Ignore scope operators. - (forward-char) - (setq c-maybe-labelp (1- (point))))) - ((eq (char-after) ??) - ;; A question mark. Can't be a label, so stop - ;; looking for more : and ?. - (setq c-maybe-labelp nil - skip-chars (substring c-stmt-delim-chars 0 -2))) - ((and (eolp) ; Can only happen in AWK Mode - (not (c-awk-completed-stmt-ws-ends-line-p))) - (forward-char)) - ((and (c-mode-is-new-awk-p) - (bolp) lit-range ; awk: comment/string ended prev line. - (not (c-awk-completed-stmt-ws-ends-prev-line-p)))) - (t (throw 'done (point)))))) - nil)))) + (cond + ((setq lit-range (c-literal-limits from)) ; Have we landed in a string/comment? + (goto-char (cdr lit-range))) + ((eq (char-after) ?:) + (forward-char) + (if (and (eq (char-after) ?:) + (< (point) to)) + ;; Ignore scope operators. + (forward-char) + (setq c-maybe-labelp (1- (point))))) + ((eq (char-after) ??) + ;; A question mark. Can't be a label, so stop + ;; looking for more : and ?. + (setq c-maybe-labelp nil + skip-chars (substring c-stmt-delim-chars 0 -2))) + ((memq (char-after) '(?# ?\n ?\r)) ; A virtual semicolon? + (if (and (eq (char-before) ?\\) (memq (char-after) '(?\n ?\r))) + (backward-char)) + (skip-chars-backward " \t" from) + (if (c-at-vsemi-p) + (throw 'done (point)) + (forward-line))) + (t (throw 'done (point))))) + ;; In trailing space after an as yet undetected virtual semicolon? + (c-backward-syntactic-ws from) + (if (and (< (point) to) + (c-at-vsemi-p)) + (point) + nil))))) + +(defun c-at-statement-start-p () + "Return non-nil if the point is at the first token in a statement +or somewhere in the syntactic whitespace before it. + +A \"statement\" here is not restricted to those inside code blocks. +Any kind of declaration-like construct that occur outside function +bodies is also considered a \"statement\". + +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." + + (save-excursion + (let ((end (point)) + c-maybe-labelp) + (c-syntactic-skip-backward (substring c-stmt-delim-chars 1) nil t) + (or (bobp) + (eq (char-before) ?}) + (and (eq (char-before) ?{) + (not (and c-special-brace-lists + (progn (backward-char) + (c-looking-at-special-brace-list))))) + (c-crosses-statement-barrier-p (point) end))))) + +(defun c-at-expression-start-p () + "Return non-nil if the point is at the first token in an expression or +statement, or somewhere in the syntactic whitespace before it. + +An \"expression\" here is a bit different from the normal language +grammar sense: It's any sequence of expression tokens except commas, +unless they are enclosed inside parentheses of some kind. Also, an +expression never continues past an enclosing parenthesis, but it might +contain parenthesis pairs of any sort except braces. + +Since expressions never cross statement boundaries, this function also +recognizes statement beginnings, just like `c-at-statement-start-p'. + +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." + + (save-excursion + (let ((end (point)) + (c-stmt-delim-chars c-stmt-delim-chars-with-comma) + c-maybe-labelp) + (c-syntactic-skip-backward (substring c-stmt-delim-chars 1) nil t) + (or (bobp) + (memq (char-before) '(?{ ?})) + (save-excursion (backward-char) + (looking-at "\\s(")) + (c-crosses-statement-barrier-p (point) end))))) ;; A set of functions that covers various idiosyncrasies in @@ -1020,7 +1189,8 @@ Line continuations, i.e. a backslashes followed by line breaks, are treated as whitespace. -This function does not do any hidden buffer changes." +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." (while (or ;; If forward-comment in at least XEmacs 21 is given a large @@ -1054,8 +1224,7 @@ (while (progn (skip-chars-backward " \t\n\r\f\v") (and (looking-at "[\n\r]") - (eq (char-before) ?\\) - (< (point) start))) + (eq (char-before) ?\\))) (backward-char)) (if (bobp) @@ -1088,13 +1257,16 @@ Line continuations, i.e. a backslashes followed by line breaks, are treated as whitespace. The line breaks that end line comments are considered to be the comment enders, so the point cannot be at the end -of the same line to move over a line comment. - -This function does not do any hidden buffer changes." +of the same line to move over a line comment. Unlike +c-backward-syntactic-ws, this function doesn't move back over +preprocessor directives. + +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." (let ((start (point))) (while (and - ;; `forward-comment' in some emacsen (e.g. Emacs 19.34) + ;; `forward-comment' in some emacsen (e.g. XEmacs 21.4) ;; return t when moving backwards at bob. (not (bobp)) @@ -1189,7 +1361,7 @@ ; ;; properties in the buffer. ; (interactive) ; (save-excursion -; (let (in-face) +; (c-save-buffer-state (in-face) ; (goto-char (point-min)) ; (setq in-face (if (get-text-property (point) 'c-is-sws) ; (point))) @@ -1220,30 +1392,35 @@ ) (defmacro c-put-is-sws (beg end) + ;; This macro does a hidden buffer change. `(let ((beg ,beg) (end ,end)) (put-text-property beg end 'c-is-sws t) ,@(when (facep 'c-debug-is-sws-face) `((c-debug-add-face beg end 'c-debug-is-sws-face))))) (defmacro c-put-in-sws (beg end) + ;; This macro does a hidden buffer change. `(let ((beg ,beg) (end ,end)) (put-text-property beg end 'c-in-sws t) ,@(when (facep 'c-debug-is-sws-face) `((c-debug-add-face beg end 'c-debug-in-sws-face))))) (defmacro c-remove-is-sws (beg end) + ;; This macro does a hidden buffer change. `(let ((beg ,beg) (end ,end)) (remove-text-properties beg end '(c-is-sws nil)) ,@(when (facep 'c-debug-is-sws-face) `((c-debug-remove-face beg end 'c-debug-is-sws-face))))) (defmacro c-remove-in-sws (beg end) + ;; This macro does a hidden buffer change. `(let ((beg ,beg) (end ,end)) (remove-text-properties beg end '(c-in-sws nil)) ,@(when (facep 'c-debug-is-sws-face) `((c-debug-remove-face beg end 'c-debug-in-sws-face))))) (defmacro c-remove-is-and-in-sws (beg end) + ;; This macro does a hidden buffer change. `(let ((beg ,beg) (end ,end)) (remove-text-properties beg end '(c-is-sws nil c-in-sws nil)) ,@(when (facep 'c-debug-is-sws-face) @@ -1255,6 +1432,8 @@ ;; `c-forward-sws' or `c-backward-sws' are used outside ;; `c-save-buffer-state' or similar then this will remove the cache ;; properties right after they're added. + ;; + ;; This function does hidden buffer changes. (save-excursion ;; Adjust the end to remove the properties in any following simple @@ -1291,6 +1470,8 @@ (defun c-forward-sws () ;; Used by `c-forward-syntactic-ws' to implement the unbounded search. + ;; + ;; This function might do hidden buffer changes. (let (;; `rung-pos' is set to a position as early as possible in the ;; unmarked part of the simple ws region. @@ -1483,6 +1664,8 @@ (defun c-backward-sws () ;; Used by `c-backward-syntactic-ws' to implement the unbounded search. + ;; + ;; This function might do hidden buffer changes. (let (;; `rung-pos' is set to a position as late as possible in the unmarked ;; part of the simple ws region. @@ -1703,12 +1886,13 @@ ))) -;; A system for handling noteworthy parens before the point. +;; A system for finding noteworthy parens before the point. (defvar c-state-cache nil) (make-variable-buffer-local 'c-state-cache) ;; The state cache used by `c-parse-state' to cut down the amount of ;; searching. It's the result from some earlier `c-parse-state' call. +;; ;; The use of the cached info is more effective if the next ;; `c-parse-state' call is on a line close by the one the cached state ;; was made at; the cache can actually slow down a little if the @@ -1722,24 +1906,58 @@ ;; change of narrowing is likely to affect the parens that are visible ;; before the point. +(defvar c-state-cache-good-pos 1) +(make-variable-buffer-local 'c-state-cache-good-pos) +;; This is a position where `c-state-cache' is known to be correct. +;; It's a position inside one of the recorded unclosed parens or the +;; top level, but not further nested inside any literal or subparen +;; that is closed before the last recorded position. +;; +;; The exact position is chosen to try to be close to yet earlier than +;; the position where `c-state-cache' will be called next. Right now +;; the heuristic is to set it to the position after the last found +;; closing paren (of any type) before the line on which +;; `c-parse-state' was called. That is chosen primarily to work well +;; with refontification of the current line. + (defsubst c-invalidate-state-cache (pos) ;; Invalidate all info on `c-state-cache' that applies to the buffer ;; at POS or higher. This is much like `c-whack-state-after', but ;; it never changes a paren pair element into an open paren element. ;; Doing that would mean that the new open paren wouldn't have the ;; required preceding paren pair element. - ;; - ;; This function does not do any hidden buffer changes. - (while (and c-state-cache + (while (and (or c-state-cache + (when (< pos c-state-cache-good-pos) + (setq c-state-cache-good-pos 1) + nil)) (let ((elem (car c-state-cache))) (if (consp elem) - (or (<= pos (car elem)) - (< pos (cdr elem))) - (<= pos elem)))) + (or (< pos (cdr elem)) + (when (< pos c-state-cache-good-pos) + (setq c-state-cache-good-pos (cdr elem)) + nil)) + (or (<= pos elem) + (when (< pos c-state-cache-good-pos) + (setq c-state-cache-good-pos (1+ elem)) + nil))))) (setq c-state-cache (cdr c-state-cache)))) +(defun c-get-fallback-start-pos (here) + ;; Return the start position for building `c-state-cache' from + ;; scratch. + (save-excursion + ;; Go back 2 bods, but ignore any bogus positions returned by + ;; beginning-of-defun (i.e. open paren in column zero). + (goto-char here) + (let ((cnt 2)) + (while (not (or (bobp) (zerop cnt))) + (c-beginning-of-defun-1) + (if (eq (char-after) ?\{) + (setq cnt (1- cnt))))) + (point))) + (defun c-parse-state () - ;; Finds and records all noteworthy parens between some good point + ;; Find and record all noteworthy parens between some good point ;; earlier in the file and point. That good point is at least the ;; beginning of the top-level construct we are in, or the beginning ;; of the preceding top-level construct if we aren't in one. @@ -1750,22 +1968,32 @@ ;; the point. If an element is a cons, it gives the position of a ;; closed brace paren pair; the car is the start paren position and ;; the cdr is the position following the closing paren. Only the - ;; last closed brace paren pair before each open paren is recorded, - ;; and thus the state never contains two cons elements in - ;; succession. + ;; last closed brace paren pair before each open paren and before + ;; the point is recorded, and thus the state never contains two cons + ;; elements in succession. ;; ;; Currently no characters which are given paren syntax with the ;; syntax-table property are recorded, i.e. angle bracket arglist ;; parens are never present here. Note that this might change. ;; - ;; This function does not do any hidden buffer changes. + ;; BUG: This function doesn't cope entirely well with unbalanced + ;; parens in macros. E.g. in the following case the brace before + ;; the macro isn't balanced with the one after it: + ;; + ;; { + ;; #define X { + ;; } + ;; + ;; This function might do hidden buffer changes. (save-restriction (let* ((here (point)) + (here-bol (c-point 'bol)) (c-macro-start (c-query-macro-start)) (in-macro-start (or c-macro-start (point))) - old-state last-pos pairs pos save-pos) - (c-invalidate-state-cache (point)) + old-state last-pos brace-pair-open brace-pair-close + pos save-pos) + (c-invalidate-state-cache here) ;; If the minimum position has changed due to narrowing then we ;; have to fix the tail of `c-state-cache' accordingly. @@ -1780,12 +2008,14 @@ (setq ptr (cdr ptr))) (when (consp ptr) (if (eq (cdr ptr) c-state-cache) - (setq c-state-cache nil) + (setq c-state-cache nil + c-state-cache-good-pos 1) (setcdr ptr nil)))) ;; If point-min has moved backward then we drop the state ;; completely. It's possible to do a better job here and ;; recalculate the top only. - (setq c-state-cache nil)) + (setq c-state-cache nil + c-state-cache-good-pos 1)) (setq c-state-cache-start (point-min))) ;; Get the latest position we know are directly inside the @@ -1794,115 +2024,152 @@ (if (consp (car c-state-cache)) (cdr (car c-state-cache)) (1+ (car c-state-cache))))) - - ;; Check if the found last-pos is in a macro. If it is, and - ;; we're not in the same macro, we must discard everything on - ;; c-state-cache that is inside the macro before using it. - (when last-pos - (save-excursion - (goto-char last-pos) - (when (and (c-beginning-of-macro) - (/= (point) in-macro-start)) - (c-invalidate-state-cache (point)) - ;; Set last-pos again, just like above. - (setq last-pos (and c-state-cache - (if (consp (car c-state-cache)) - (cdr (car c-state-cache)) - (1+ (car c-state-cache)))))))) - - (setq pos - ;; Find the start position for the forward search. (Can't - ;; search in the backward direction since point might be - ;; in some kind of literal.) - (or (when last-pos - - ;; There's a cached state with a containing paren. Pop - ;; off the stale containing sexps from it by going - ;; forward out of parens as far as possible. - (narrow-to-region (point-min) here) - (let (placeholder pair-beg) - (while (and c-state-cache - (setq placeholder - (c-up-list-forward last-pos))) - (setq last-pos placeholder) - (if (consp (car c-state-cache)) - (setq pair-beg (car-safe (cdr c-state-cache)) - c-state-cache (cdr-safe (cdr c-state-cache))) - (setq pair-beg (car c-state-cache) - c-state-cache (cdr c-state-cache)))) - - (when (and pair-beg (eq (char-after pair-beg) ?{)) - ;; The last paren pair we moved out from was a brace - ;; pair. Modify the state to record this as a closed - ;; pair now. - (if (consp (car-safe c-state-cache)) - (setq c-state-cache (cdr c-state-cache))) - (setq c-state-cache (cons (cons pair-beg last-pos) - c-state-cache)))) - - ;; Check if the preceding balanced paren is within a - ;; macro; it should be ignored if we're outside the - ;; macro. There's no need to check any further upwards; - ;; if the macro contains an unbalanced opening paren then - ;; we're smoked anyway. - (when (and (<= (point) in-macro-start) - (consp (car c-state-cache))) - (save-excursion - (goto-char (car (car c-state-cache))) - (when (c-beginning-of-macro) - (setq here (point) - c-state-cache (cdr c-state-cache))))) - - (when c-state-cache - (setq old-state c-state-cache) - last-pos)) - - (save-excursion - ;; go back 2 bods, but ignore any bogus positions - ;; returned by beginning-of-defun (i.e. open paren in - ;; column zero) - (goto-char here) - (let ((cnt 2)) - (while (not (or (bobp) (zerop cnt))) - (c-beginning-of-defun-1) - (if (eq (char-after) ?\{) - (setq cnt (1- cnt))))) - (point)))) + (if (or (not last-pos) + (< last-pos c-state-cache-good-pos)) + (setq last-pos c-state-cache-good-pos) + ;; Take the opportunity to move the cached good position + ;; further down. + (if (< last-pos here-bol) + (setq c-state-cache-good-pos last-pos))) + + ;; Check if `last-pos' is in a macro. If it is, and we're not + ;; in the same macro, we must discard everything on + ;; `c-state-cache' that is inside the macro before using it. + (save-excursion + (goto-char last-pos) + (when (and (c-beginning-of-macro) + (/= (point) in-macro-start)) + (c-invalidate-state-cache (point)) + ;; Set `last-pos' again just like above except that there's + ;; no use looking at `c-state-cache-good-pos' here. + (setq last-pos (if c-state-cache + (if (consp (car c-state-cache)) + (cdr (car c-state-cache)) + (1+ (car c-state-cache))) + 1)))) + + ;; If we've moved very far from the last cached position then + ;; it's probably better to redo it from scratch, otherwise we + ;; might spend a lot of time searching from `last-pos' down to + ;; here. + (when (< last-pos (- here 20000)) + ;; First get the fallback start position. If it turns out + ;; that it's so far back that the cached state is closer then + ;; we'll keep it afterall. + (setq pos (c-get-fallback-start-pos here)) + (if (<= pos last-pos) + (setq pos nil) + (setq last-pos nil + c-state-cache nil + c-state-cache-good-pos 1))) + + ;; Find the start position for the forward search. (Can't + ;; search in the backward direction since the point might be in + ;; some kind of literal.) + + (unless pos + (setq old-state c-state-cache) + + ;; There's a cached state with a containing paren. Pop off + ;; the stale containing sexps from it by going forward out of + ;; parens as far as possible. + (narrow-to-region (point-min) here) + (let (placeholder pair-beg) + (while (and c-state-cache + (setq placeholder + (c-up-list-forward last-pos))) + (setq last-pos placeholder) + (if (consp (car c-state-cache)) + (setq pair-beg (car-safe (cdr c-state-cache)) + c-state-cache (cdr-safe (cdr c-state-cache))) + (setq pair-beg (car c-state-cache) + c-state-cache (cdr c-state-cache)))) + + (when (and pair-beg (eq (char-after pair-beg) ?{)) + ;; The last paren pair we moved out from was a brace + ;; pair. Modify the state to record this as a closed + ;; pair now. + (if (consp (car-safe c-state-cache)) + (setq c-state-cache (cdr c-state-cache))) + (setq c-state-cache (cons (cons pair-beg last-pos) + c-state-cache)))) + + ;; Check if the preceding balanced paren is within a + ;; macro; it should be ignored if we're outside the + ;; macro. There's no need to check any further upwards; + ;; if the macro contains an unbalanced opening paren then + ;; we're smoked anyway. + (when (and (<= (point) in-macro-start) + (consp (car c-state-cache))) + (save-excursion + (goto-char (car (car c-state-cache))) + (when (c-beginning-of-macro) + (setq here (point) + c-state-cache (cdr c-state-cache))))) + + (unless (eq c-state-cache old-state) + ;; Have to adjust the cached good position if state has been + ;; popped off. + (setq c-state-cache-good-pos + (if c-state-cache + (if (consp (car c-state-cache)) + (cdr (car c-state-cache)) + (1+ (car c-state-cache))) + 1) + old-state c-state-cache)) + + (when c-state-cache + (setq pos last-pos))) + + ;; Get the fallback start position. + (unless pos + (setq pos (c-get-fallback-start-pos here) + c-state-cache nil + c-state-cache-good-pos 1)) (narrow-to-region (point-min) here) (while pos - ;; Find the balanced brace pairs. (setq save-pos pos - pairs nil) - (while (and (setq last-pos (c-down-list-forward pos)) - (setq pos (c-up-list-forward last-pos))) - (if (eq (char-before last-pos) ?{) - (setq pairs (cons (cons last-pos pos) pairs)))) - - ;; Should ignore any pairs that are in a macro, providing - ;; we're not in the same one. - (when (and pairs (< (car (car pairs)) in-macro-start)) - (while (and (save-excursion - (goto-char (car (car pairs))) - (c-beginning-of-macro)) - (setq pairs (cdr pairs))))) + brace-pair-open nil) + + ;; Find the balanced brace pairs. This loop is hot, so it + ;; does ugly tricks to go faster. + (c-safe + (let (set-good-pos set-brace-pair) + (while t + (setq last-pos nil + last-pos (scan-lists pos 1 -1)) ; Might signal. + (setq pos (scan-lists last-pos 1 1) ; Might signal. + set-good-pos (< pos here-bol) + set-brace-pair (eq (char-before last-pos) ?{)) + + ;; Update the cached good position and record the brace + ;; pair, whichever is applicable for the paren we've + ;; just jumped over. But first check that it isn't + ;; inside a macro and the point isn't inside the same + ;; one. + (when (and (or set-good-pos set-brace-pair) + (or (>= pos in-macro-start) + (save-excursion + (goto-char pos) + (not (c-beginning-of-macro))))) + (if set-good-pos + (setq c-state-cache-good-pos pos)) + (if set-brace-pair + (setq brace-pair-open last-pos + brace-pair-close pos)))))) ;; Record the last brace pair. - (when pairs - (if (and (eq c-state-cache old-state) - (consp (car-safe c-state-cache))) - ;; There's a closed pair on the cached state but we've - ;; found a later one, so remove it. - (setq c-state-cache (cdr c-state-cache))) - (setq pairs (car pairs)) - (setcar pairs (1- (car pairs))) - (when (consp (car-safe c-state-cache)) - ;; There could already be a cons first in `c-state-cache' - ;; if we've e.g. jumped over an unbalanced open paren in a - ;; macro below. - (setq c-state-cache (cdr c-state-cache))) - (setq c-state-cache (cons pairs c-state-cache))) + (when brace-pair-open + (let ((head (car-safe c-state-cache))) + (if (consp head) + (progn + (setcar head (1- brace-pair-open)) + (setcdr head brace-pair-close)) + (setq c-state-cache (cons (cons (1- brace-pair-open) + brace-pair-close) + c-state-cache))))) (if last-pos ;; Prepare to loop, but record the open paren only if it's @@ -1911,16 +2178,18 @@ ;; that got an open paren syntax-table property. (progn (setq pos last-pos) - (if (and (or (>= last-pos in-macro-start) - (save-excursion - (goto-char last-pos) - (not (c-beginning-of-macro)))) - ;; Check for known types of parens that we want - ;; to record. The syntax table is not to be - ;; trusted here since the caller might be using - ;; e.g. `c++-template-syntax-table'. - (memq (char-before last-pos) '(?{ ?\( ?\[))) - (setq c-state-cache (cons (1- last-pos) c-state-cache)))) + (when (and (or (>= last-pos in-macro-start) + (save-excursion + (goto-char last-pos) + (not (c-beginning-of-macro)))) + ;; Check for known types of parens that we + ;; want to record. The syntax table is not to + ;; be trusted here since the caller might be + ;; using e.g. `c++-template-syntax-table'. + (memq (char-before last-pos) '(?{ ?\( ?\[))) + (if (< last-pos here-bol) + (setq c-state-cache-good-pos last-pos)) + (setq c-state-cache (cons (1- last-pos) c-state-cache)))) (if (setq last-pos (c-up-list-forward pos)) ;; Found a close paren without a corresponding opening @@ -1928,7 +2197,8 @@ ;; scan backward for the start paren and then start over. (progn (setq pos (c-up-list-backward pos) - c-state-cache nil) + c-state-cache nil + c-state-cache-good-pos c-state-cache-start) (when (or (not pos) ;; Emacs (up to at least 21.2) can get confused by ;; open parens in column zero inside comments: The @@ -1943,6 +2213,7 @@ (c-point 'bol last-pos))))))) (setq pos nil)))) + ;;(message "c-parse-state: %S end: %S" c-state-cache c-state-cache-good-pos) c-state-cache))) ;; Debug tool to catch cache inconsistencies. @@ -1952,11 +2223,23 @@ (cc-bytecomp-defun c-real-parse-state) (defun c-debug-parse-state () (let ((res1 (c-real-parse-state)) res2) - (let ((c-state-cache nil)) + (let ((c-state-cache nil) + (c-state-cache-start 1) + (c-state-cache-good-pos 1)) (setq res2 (c-real-parse-state))) (unless (equal res1 res2) - (error "c-parse-state inconsistency: using cache: %s, from scratch: %s" - res1 res2)) + ;; The cache can actually go further back due to the ad-hoc way + ;; the first paren is found, so try to whack off a bit of its + ;; start before complaining. + (save-excursion + (goto-char (or (c-least-enclosing-brace res2) (point))) + (c-beginning-of-defun-1) + (while (not (or (bobp) (eq (char-after) ?{))) + (c-beginning-of-defun-1)) + (unless (equal (c-whack-state-before (point) res1) res2) + (message (concat "c-parse-state inconsistency: " + "using cache: %s, from scratch: %s") + res1 res2)))) res1)) (defun c-toggle-parse-state-debug (&optional arg) (interactive "P") @@ -1965,12 +2248,12 @@ 'c-debug-parse-state 'c-real-parse-state))) (c-keep-region-active)) +(when c-debug-parse-state + (c-toggle-parse-state-debug 1)) (defun c-whack-state-before (bufpos paren-state) ;; Whack off any state information from PAREN-STATE which lies ;; before BUFPOS. Not destructive on PAREN-STATE. - ;; - ;; This function does not do any hidden buffer changes. (let* ((newstate (list nil)) (ptr newstate) car) @@ -1986,8 +2269,6 @@ (defun c-whack-state-after (bufpos paren-state) ;; Whack off any state information from PAREN-STATE which lies at or ;; after BUFPOS. Not destructive on PAREN-STATE. - ;; - ;; This function does not do any hidden buffer changes. (catch 'done (while paren-state (let ((car (car paren-state))) @@ -2018,9 +2299,7 @@ (defun c-most-enclosing-brace (paren-state &optional bufpos) ;; Return the bufpos of the innermost enclosing open paren before - ;; bufpos that hasn't been narrowed out, or nil if none was found. - ;; - ;; This function does not do any hidden buffer changes. + ;; bufpos, or nil if none was found. (let (enclosingp) (or bufpos (setq bufpos 134217727)) (while paren-state @@ -2029,34 +2308,31 @@ (if (or (consp enclosingp) (>= enclosingp bufpos)) (setq enclosingp nil) - (if (< enclosingp (point-min)) - (setq enclosingp nil)) (setq paren-state nil))) enclosingp)) -(defun c-least-enclosing-brace (paren-state &optional bufpos) - ;; Return the bufpos of the outermost enclosing open paren before - ;; bufpos that hasn't been narrowed out, or nil if none was found. - ;; - ;; This function does not do any hidden buffer changes. +(defun c-least-enclosing-brace (paren-state) + ;; Return the bufpos of the outermost enclosing open paren, or nil + ;; if none was found. (let (pos elem) - (or bufpos (setq bufpos 134217727)) (while paren-state (setq elem (car paren-state) paren-state (cdr paren-state)) - (unless (or (consp elem) - (>= elem bufpos)) - (if (>= elem (point-min)) - (setq pos elem)))) + (if (integerp elem) + (setq pos elem))) pos)) (defun c-safe-position (bufpos paren-state) - ;; Return the closest known safe position higher up than BUFPOS, or - ;; nil if PAREN-STATE doesn't contain one. Return nil if BUFPOS is - ;; nil, which is useful to find the closest limit before a given - ;; limit that might be nil. - ;; - ;; This function does not do any hidden buffer changes. + ;; Return the closest "safe" position recorded on PAREN-STATE that + ;; is higher up than BUFPOS. Return nil if PAREN-STATE doesn't + ;; contain any. Return nil if BUFPOS is nil, which is useful to + ;; find the closest limit before a given limit that might be nil. + ;; + ;; A "safe" position is a position at or after a recorded open + ;; paren, or after a recorded close paren. The returned position is + ;; thus either the first position after a close brace, or the first + ;; position after an enclosing paren, or at the enclosing paren in + ;; case BUFPOS is immediately after it. (when bufpos (let (elem) (catch 'done @@ -2118,33 +2394,61 @@ "Return non-nil if the point is on or directly after an identifier. Keywords are recognized and not considered identifiers. If an identifier is detected, the returned value is its starting position. -If an identifier both starts and stops at the point \(can only happen -in Pike) then the point for the preceding one is returned. - -This function does not do any hidden buffer changes." +If an identifier ends at the point and another begins at it \(can only +happen in Pike) then the point for the preceding one is returned. + +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." + + ;; FIXME: Shouldn't this function handle "operator" in C++? (save-excursion - (if (zerop (skip-syntax-backward "w_")) - - (when (c-major-mode-is 'pike-mode) - ;; Handle the ` syntax in Pike. - (let ((pos (point))) - (skip-chars-backward "-!%&*+/<=>^|~[]()") - (and (if (< (skip-chars-backward "`") 0) - t - (goto-char pos) - (eq (char-after) ?\`)) - (looking-at c-symbol-key) - (>= (match-end 0) pos) - (point)))) - - (and (not (looking-at c-keywords-regexp)) - (point))))) + (skip-syntax-backward "w_") + + (or + + ;; Check for a normal (non-keyword) identifier. + (and (looking-at c-symbol-start) + (not (looking-at c-keywords-regexp)) + (point)) + + (when (c-major-mode-is 'pike-mode) + ;; Handle the ` syntax in Pike. + (let ((pos (point))) + (skip-chars-backward "-!%&*+/<=>^|~[]()") + (and (if (< (skip-chars-backward "`") 0) + t + (goto-char pos) + (eq (char-after) ?\`)) + (looking-at c-symbol-key) + (>= (match-end 0) pos) + (point)))) + + ;; Handle the "operator +" syntax in C++. + (when (and c-overloadable-operators-regexp + (= (c-backward-token-2 0) 0)) + + (cond ((and (looking-at c-overloadable-operators-regexp) + (or (not c-opt-op-identitier-prefix) + (and (= (c-backward-token-2 1) 0) + (looking-at c-opt-op-identitier-prefix)))) + (point)) + + ((save-excursion + (and c-opt-op-identitier-prefix + (looking-at c-opt-op-identitier-prefix) + (= (c-forward-token-2 1) 0) + (looking-at c-overloadable-operators-regexp))) + (point)))) + + ))) (defsubst c-simple-skip-symbol-backward () ;; If the point is at the end of a symbol then skip backward to the ;; beginning of it. Don't move otherwise. Return non-nil if point ;; moved. + ;; + ;; This function might do hidden buffer changes. (or (< (skip-syntax-backward "w_") 0) (and (c-major-mode-is 'pike-mode) ;; Handle the ` syntax in Pike. @@ -2157,11 +2461,13 @@ (goto-char pos) nil))))) -(defsubst c-beginning-of-current-token (&optional back-limit) +(defun c-beginning-of-current-token (&optional back-limit) ;; Move to the beginning of the current token. Do not move if not ;; in the middle of one. BACK-LIMIT may be used to bound the ;; backward search; if given it's assumed to be at the boundary ;; between two tokens. + ;; + ;; This function might do hidden buffer changes. (if (looking-at "\\w\\|\\s_") (skip-syntax-backward "w_" back-limit) (let ((start (point))) @@ -2183,6 +2489,8 @@ ;; middle of one. BACK-LIMIT may be used to bound the backward ;; search; if given it's assumed to be at the boundary between two ;; tokens. Return non-nil if the point is moved, nil otherwise. + ;; + ;; This function might do hidden buffer changes. (let ((start (point))) (cond ((< (skip-syntax-backward "w_" (1- start)) 0) (skip-syntax-forward "w_")) @@ -2228,7 +2536,10 @@ that if COUNT is 0 and no appropriate token beginning is found, 1 will be returned. Thus, a return value of 0 guarantees that point is at the requested position and a return value less \(without signs) than -COUNT guarantees that point is at the beginning of some token." +COUNT guarantees that point is at the beginning of some token. + +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." (or count (setq count 1)) (if (< count 0) @@ -2417,7 +2728,10 @@ Bug: Unbalanced parens inside cpp directives are currently not handled correctly \(i.e. they don't get ignored as they should) when -PAREN-LEVEL is set." +PAREN-LEVEL is set. + +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." (or bound (setq bound (point-max))) (if paren-level (setq paren-level -1)) @@ -2601,23 +2915,39 @@ (goto-char bound)) nil))) -(defun c-syntactic-skip-backward (skip-chars &optional limit) +(defun c-syntactic-skip-backward (skip-chars &optional limit paren-level) "Like `skip-chars-backward' but only look at syntactically relevant chars, i.e. don't stop at positions inside syntactic whitespace or string literals. Preprocessor directives are also ignored, with the exception of the one that the point starts within, if any. If LIMIT is given, -it's assumed to be at a syntactically relevant position." +it's assumed to be at a syntactically relevant position. + +If PAREN-LEVEL is non-nil, the function won't stop in nested paren +sexps, and the search will also not go outside the current paren sexp. +However, if LIMIT or the buffer limit is reached inside a nested paren +then the point will be left at the limit. + +Non-nil is returned if the point moved, nil otherwise. + +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." (let ((start (point)) + state ;; A list of syntactically relevant positions in descending ;; order. It's used to avoid scanning repeatedly over ;; potentially large regions with `parse-partial-sexp' to verify ;; each position. safe-pos-list + ;; The position at the beginning of `safe-pos-list'. + safe-pos ;; The result from `c-beginning-of-macro' at the start position or the ;; start position itself if it isn't within a macro. Evaluated on ;; demand. - start-macro-beg) + start-macro-beg + ;; The earliest position after the current one with the same paren + ;; level. Used only when `paren-level' is set. + (paren-level-pos (point))) (while (progn (while (and @@ -2626,7 +2956,7 @@ ;; Use `parse-partial-sexp' from a safe position down to ;; the point to check if it's outside comments and ;; strings. - (let ((pos (point)) safe-pos state) + (let ((pos (point)) state-2 pps-end-pos) ;; Pick a safe position as close to the point as ;; possible. ;; @@ -2643,13 +2973,18 @@ (point-min)) safe-pos-list (list safe-pos))) + ;; Cache positions along the way to use if we have to + ;; back up more. We cache every closing paren on the + ;; same level. If the paren cache is relevant in this + ;; region then we're typically already on the same + ;; level as the target position. Note that we might + ;; cache positions after opening parens in case + ;; safe-pos is in a nested list. That's both uncommon + ;; and harmless. (while (progn (setq state (parse-partial-sexp safe-pos pos 0)) (< (point) pos)) - ;; Cache positions along the way to use if we have to - ;; back up more. Every closing paren on the same - ;; level seems like fairly well spaced positions. (setq safe-pos (point) safe-pos-list (cons safe-pos safe-pos-list))) @@ -2657,13 +2992,50 @@ ((or (elt state 3) (elt state 4)) ;; Inside string or comment. Continue search at the ;; beginning of it. - (if (setq pos (nth 8 state)) - ;; It's an emacs where `parse-partial-sexp' - ;; supplies the starting position. - (goto-char pos) - (goto-char (car (c-literal-limits safe-pos)))) + (goto-char (elt state 8)) t) + ((and paren-level + (save-excursion + (setq state-2 (parse-partial-sexp + pos paren-level-pos -1) + pps-end-pos (point)) + (/= (car state-2) 0))) + ;; Not at the right level. + + (if (and (< (car state-2) 0) + ;; We stop above if we go out of a paren. + ;; Now check whether it precedes or is + ;; nested in the starting sexp. + (save-excursion + (setq state-2 + (parse-partial-sexp + pps-end-pos paren-level-pos + nil nil state-2)) + (< (car state-2) 0))) + + ;; We've stopped short of the starting position + ;; so the hit was inside a nested list. Go up + ;; until we are at the right level. + (condition-case nil + (progn + (goto-char (scan-lists pos -1 + (- (car state-2)))) + (setq paren-level-pos (point)) + (if (and limit (>= limit paren-level-pos)) + (progn + (goto-char limit) + nil) + t)) + (error + (goto-char (or limit (point-min))) + nil)) + + ;; The hit was outside the list at the start + ;; position. Go to the start of the list and exit. + (goto-char (1+ (elt state-2 1))) + nil)) + ((c-beginning-of-macro limit) ;; Inside a macro. (if (< (point) @@ -2674,10 +3046,20 @@ (c-beginning-of-macro limit) (point))))) t + ;; It's inside the same macro we started in so it's ;; a relevant match. (goto-char pos) - nil)))))) + nil))))) + + ;; If the state contains the start of the containing sexp we + ;; cache that position too, so that parse-partial-sexp in the + ;; next run has a bigger chance of starting at the same level + ;; as the target position and thus will get more good safe + ;; positions into the list. + (if (elt state 1) + (setq safe-pos (1+ (elt state 1)) + safe-pos-list (cons safe-pos safe-pos-list)))) (> (point) (progn @@ -2686,7 +3068,124 @@ (c-backward-syntactic-ws) (point))))) - (- (point) start))) + ;; We might want to extend this with more useful return values in + ;; the future. + (/= (point) start))) + +;; The following is an alternative implementation of +;; `c-syntactic-skip-backward' that uses backward movement to keep +;; track of the syntactic context. It turned out to be generally +;; slower than the one above which uses forward checks from earlier +;; safe positions. +;; +;;(defconst c-ssb-stop-re +;; ;; The regexp matching chars `c-syntactic-skip-backward' needs to +;; ;; stop at to avoid going into comments and literals. +;; (concat +;; ;; Match comment end syntax and string literal syntax. Also match +;; ;; '/' for block comment endings (not covered by comment end +;; ;; syntax). +;; "\\s>\\|/\\|\\s\"" +;; (if (memq 'gen-string-delim c-emacs-features) +;; "\\|\\s|" +;; "") +;; (if (memq 'gen-comment-delim c-emacs-features) +;; "\\|\\s!" +;; ""))) +;; +;;(defconst c-ssb-stop-paren-re +;; ;; Like `c-ssb-stop-re' but also stops at paren chars. +;; (concat c-ssb-stop-re "\\|\\s(\\|\\s)")) +;; +;;(defconst c-ssb-sexp-end-re +;; ;; Regexp matching the ending syntax of a complex sexp. +;; (concat c-string-limit-regexp "\\|\\s)")) +;; +;;(defun c-syntactic-skip-backward (skip-chars &optional limit paren-level) +;; "Like `skip-chars-backward' but only look at syntactically relevant chars, +;;i.e. don't stop at positions inside syntactic whitespace or string +;;literals. Preprocessor directives are also ignored. However, if the +;;point is within a comment, string literal or preprocessor directory to +;;begin with, its contents is treated as syntactically relevant chars. +;;If LIMIT is given, it limits the backward search and the point will be +;;left there if no earlier position is found. +;; +;;If PAREN-LEVEL is non-nil, the function won't stop in nested paren +;;sexps, and the search will also not go outside the current paren sexp. +;;However, if LIMIT or the buffer limit is reached inside a nested paren +;;then the point will be left at the limit. +;; +;;Non-nil is returned if the point moved, nil otherwise. +;; +;;Note that this function might do hidden buffer changes. See the +;;comment at the start of cc-engine.el for more info." +;; +;; (save-restriction +;; (when limit +;; (narrow-to-region limit (point-max))) +;; +;; (let ((start (point))) +;; (catch 'done +;; (while (let ((last-pos (point)) +;; (stop-pos (progn +;; (skip-chars-backward skip-chars) +;; (point)))) +;; +;; ;; Skip back over the same region as +;; ;; `skip-chars-backward' above, but keep to +;; ;; syntactically relevant positions. +;; (goto-char last-pos) +;; (while (and +;; ;; `re-search-backward' with a single char regexp +;; ;; should be fast. +;; (re-search-backward +;; (if paren-level c-ssb-stop-paren-re c-ssb-stop-re) +;; stop-pos 'move) +;; +;; (progn +;; (cond +;; ((looking-at "\\s(") +;; ;; `paren-level' is set and we've found the +;; ;; start of the containing paren. +;; (forward-char) +;; (throw 'done t)) +;; +;; ((looking-at c-ssb-sexp-end-re) +;; ;; We're at the end of a string literal or paren +;; ;; sexp (if `paren-level' is set). +;; (forward-char) +;; (condition-case nil +;; (c-backward-sexp) +;; (error +;; (goto-char limit) +;; (throw 'done t)))) +;; +;; (t +;; (forward-char) +;; ;; At the end of some syntactic ws or possibly +;; ;; after a plain '/' operator. +;; (let ((pos (point))) +;; (c-backward-syntactic-ws) +;; (if (= pos (point)) +;; ;; Was a plain '/' operator. Go past it. +;; (backward-char))))) +;; +;; (> (point) stop-pos)))) +;; +;; ;; Now the point is either at `stop-pos' or at some +;; ;; position further back if `stop-pos' was at a +;; ;; syntactically irrelevant place. +;; +;; ;; Skip additional syntactic ws so that we don't stop +;; ;; at the end of a comment if `skip-chars' is +;; ;; something like "^/". +;; (c-backward-syntactic-ws) +;; +;; (< (point) stop-pos)))) +;; +;; ;; We might want to extend this with more useful return values +;; ;; in the future. +;; (/= (point) start)))) ;; Tools for handling comments and string literals. @@ -2702,7 +3201,9 @@ The last point calculated is cached if the cache is enabled, i.e. if `c-in-literal-cache' is bound to a two element vector. -This function does not do any hidden buffer changes." +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." + (if (and (vectorp c-in-literal-cache) (= (point) (aref c-in-literal-cache 0))) (aref c-in-literal-cache 1) @@ -2748,6 +3249,7 @@ ;; (Alan Mackenzie, 2003/4/30). (defun c-fast-in-literal (&optional lim detect-cpp) + ;; This function might do hidden buffer changes. (let ((context (buffer-syntactic-context))) (cond ((eq context 'string) 'string) @@ -2775,104 +3277,8 @@ recognized. This only has effect for comments, which have starting delimiters with more than one character. -This function does not do any hidden buffer changes." - - (save-excursion - (let* ((pos (point)) - (lim (or lim (progn - (c-beginning-of-syntax) - (point)))) - (state (parse-partial-sexp lim pos))) - - (cond ((elt state 3) - ;; String. Search backward for the start. - (while (elt state 3) - (search-backward (make-string 1 (elt state 3))) - (setq state (parse-partial-sexp lim (point)))) - (cons (point) (or (c-safe (c-forward-sexp 1) (point)) - (point-max)))) - - ((elt state 7) - ;; Line comment. Search from bol for the comment starter. - (beginning-of-line) - (setq state (parse-partial-sexp lim (point)) - lim (point)) - (while (not (elt state 7)) - (search-forward "//") ; Should never fail. - (setq state (parse-partial-sexp - lim (point) nil nil state) - lim (point))) - (backward-char 2) - (cons (point) (progn (c-forward-single-comment) (point)))) - - ((elt state 4) - ;; Block comment. Search backward for the comment starter. - (while (elt state 4) - (search-backward "/*") ; Should never fail. - (setq state (parse-partial-sexp lim (point)))) - (cons (point) (progn (c-forward-single-comment) (point)))) - - ((and (not not-in-delimiter) - (not (elt state 5)) - (eq (char-before) ?/) - (looking-at "[/*]")) - ;; We're standing in a comment starter. - (backward-char 1) - (cons (point) (progn (c-forward-single-comment) (point)))) - - (near - (goto-char pos) - - ;; Search forward for a literal. - (skip-chars-forward " \t") - - (cond - ((looking-at c-string-limit-regexp) ; String. - (cons (point) (or (c-safe (c-forward-sexp 1) (point)) - (point-max)))) - - ((looking-at c-comment-start-regexp) ; Line or block comment. - (cons (point) (progn (c-forward-single-comment) (point)))) - - (t - ;; Search backward. - (skip-chars-backward " \t") - - (let ((end (point)) beg) - (cond - ((save-excursion - (< (skip-syntax-backward c-string-syntax) 0)) ; String. - (setq beg (c-safe (c-backward-sexp 1) (point)))) - - ((and (c-safe (forward-char -2) t) - (looking-at "*/")) - ;; Block comment. Due to the nature of line - ;; comments, they will always be covered by the - ;; normal case above. - (goto-char end) - (c-backward-single-comment) - ;; If LIM is bogus, beg will be bogus. - (setq beg (point)))) - - (if beg (cons beg end)))))) - )))) - -(defun c-literal-limits-fast (&optional lim near not-in-delimiter) - ;; Like c-literal-limits, but for emacsen whose `parse-partial-sexp' - ;; returns the pos of the comment start. - - "Return a cons of the beginning and end positions of the comment or -string surrounding point (including both delimiters), or nil if point -isn't in one. If LIM is non-nil, it's used as the \"safe\" position -to start parsing from. If NEAR is non-nil, then the limits of any -literal next to point is returned. \"Next to\" means there's only -spaces and tabs between point and the literal. The search for such a -literal is done first in forward direction. If NOT-IN-DELIMITER is -non-nil, the case when point is inside a starting delimiter won't be -recognized. This only has effect for comments, which have starting -delimiters with more than one character. - -This function does not do any hidden buffer changes." +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." (save-excursion (let* ((pos (point)) @@ -2935,8 +3341,8 @@ (if beg (cons beg end)))))) )))) -(if (memq 'pps-extended-state c-emacs-features) - (defalias 'c-literal-limits 'c-literal-limits-fast)) +;; In case external callers use this; it did have a docstring. +(defalias 'c-literal-limits-fast 'c-literal-limits) (defun c-collect-line-comments (range) "If the argument is a cons of two buffer positions (such as returned by @@ -2946,13 +3352,15 @@ empty lines or non-whitespace characters between them). Otherwise the argument is returned. -This function does not do any hidden buffer changes." +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." + (save-excursion (condition-case nil (if (and (consp range) (progn (goto-char (car range)) - (looking-at "//"))) - (let ((col (current-column)) + (looking-at c-line-comment-starter))) + (let ((col (current-column)) (beg (point)) (bopl (c-point 'bopl)) (end (cdr range))) @@ -2960,13 +3368,13 @@ ;; comments which are preceded by code. (while (and (c-backward-single-comment) (>= (point) bopl) - (looking-at "//") + (looking-at c-line-comment-starter) (= col (current-column))) (setq beg (point) bopl (c-point 'bopl))) (goto-char end) (while (and (progn (skip-chars-forward " \t") - (looking-at "//")) + (looking-at c-line-comment-starter)) (= col (current-column)) (prog1 (zerop (forward-line 1)) (setq end (point))))) @@ -2980,7 +3388,9 @@ much faster than using `c-in-literal' and is intended to be used when you need both the type of a literal and its limits. -This function does not do any hidden buffer changes." +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." + (if (consp range) (save-excursion (goto-char (car range)) @@ -3032,14 +3442,14 @@ (defmacro c-debug-put-decl-spot-faces (match-pos decl-pos) (when (facep 'c-debug-decl-spot-face) - `(let ((match-pos ,match-pos) (decl-pos ,decl-pos)) + `(c-save-buffer-state ((match-pos ,match-pos) (decl-pos ,decl-pos)) (c-debug-add-face (max match-pos (point-min)) decl-pos 'c-debug-decl-sws-face) (c-debug-add-face decl-pos (min (1+ decl-pos) (point-max)) 'c-debug-decl-spot-face)))) (defmacro c-debug-remove-decl-spot-faces (beg end) (when (facep 'c-debug-decl-spot-face) - `(progn + `(c-save-buffer-state () (c-debug-remove-face ,beg ,end 'c-debug-decl-spot-face) (c-debug-remove-face ,beg ,end 'c-debug-decl-sws-face)))) @@ -3048,6 +3458,8 @@ ;; but it contains lots of free variables that refer to things ;; inside `c-find-decl-spots'. The point is left at `cfd-match-pos' ;; if there is a match, otherwise at `cfd-limit'. + ;; + ;; This macro might do hidden buffer changes. '(progn ;; Find the next property match position if we haven't got one already. @@ -3061,21 +3473,46 @@ 'c-decl-end))))) (setq cfd-prop-match (point)))) - ;; Find the next `c-decl-prefix-re' match if we haven't got one already. + ;; Find the next `c-decl-prefix-or-start-re' match if we haven't + ;; got one already. (unless cfd-re-match - (while (and (setq cfd-re-match - (re-search-forward c-decl-prefix-re cfd-limit 'move)) - (c-got-face-at (1- (setq cfd-re-match (match-end 1))) - c-literal-faces)) - ;; Search again if the match is within a comment or a string literal. + + (if (> cfd-re-match-end (point)) + (goto-char cfd-re-match-end)) + + (while (if (setq cfd-re-match-end + (re-search-forward c-decl-prefix-or-start-re + cfd-limit 'move)) + + ;; Match. Check if it's inside a comment or string literal. + (c-got-face-at + (if (setq cfd-re-match (match-end 1)) + ;; Matched the end of a token preceding a decl spot. + (progn + (goto-char cfd-re-match) + (1- cfd-re-match)) + ;; Matched a token that start a decl spot. + (goto-char (match-beginning 0)) + (point)) + c-literal-faces) + + ;; No match. Finish up and exit the loop. + (setq cfd-re-match cfd-limit) + nil) + + ;; Skip out of comments and string literals. (while (progn (goto-char (next-single-property-change - cfd-re-match 'face nil cfd-limit)) + (point) 'face nil cfd-limit)) (and (< (point) cfd-limit) - (c-got-face-at (point) c-literal-faces))) - (setq cfd-re-match (point)))) + (c-got-face-at (point) c-literal-faces))))) + + ;; If we matched at the decl start, we have to back up over the + ;; preceding syntactic ws to set `cfd-match-pos' and to catch + ;; any decl spots in the syntactic ws. (unless cfd-re-match - (setq cfd-re-match cfd-limit))) + (c-backward-syntactic-ws) + (setq cfd-re-match (point)))) ;; Choose whichever match is closer to the start. (if (< cfd-re-match cfd-prop-match) @@ -3098,14 +3535,21 @@ (point)))))) (defun c-find-decl-spots (cfd-limit cfd-decl-re cfd-face-checklist cfd-fun) - ;; Call CFD-FUN for each possible spot for a declaration from the - ;; point to CFD-LIMIT. A spot for a declaration is the first token - ;; in the buffer and each token after the ones matched by - ;; `c-decl-prefix-re' and after the occurrences of the `c-type' - ;; property with the value `c-decl-end' (if `c-type-decl-end-used' - ;; is set). Only a spot that match CFD-DECL-RE and whose face is in - ;; the CFD-FACE-CHECKLIST list causes CFD-FUN to be called. The - ;; face check is disabled if CFD-FACE-CHECKLIST is nil. + ;; Call CFD-FUN for each possible spot for a declaration, cast or + ;; label from the point to CFD-LIMIT. Such a spot is: + ;; + ;; o The first token after bob. + ;; o The first token after the end of submatch 1 in + ;; `c-decl-prefix-or-start-re' when that submatch matches. + ;; o The start of each `c-decl-prefix-or-start-re' match when + ;; submatch 1 doesn't match. + ;; o The first token after the end of each occurence of the + ;; `c-type' text property with the value `c-decl-end', provided + ;; `c-type-decl-end-used' is set. + ;; + ;; Only a spot that match CFD-DECL-RE and whose face is in the + ;; CFD-FACE-CHECKLIST list causes CFD-FUN to be called. The face + ;; check is disabled if CFD-FACE-CHECKLIST is nil. ;; ;; If the match is inside a macro then the buffer is narrowed to the ;; end of it, so that CFD-FUN can investigate the following tokens @@ -3115,11 +3559,21 @@ ;; ;; CFD-FUN is called with point at the start of the spot. It's ;; passed two arguments: The first is the end position of the token - ;; that `c-decl-prefix-re' matched, or 0 for the implicit match at - ;; bob. The second is a flag that is t when the match is inside a - ;; macro. - ;; - ;; It's assumed that comment and strings are fontified in the + ;; preceding the spot, or 0 for the implicit match at bob. The + ;; second is a flag that is t when the match is inside a macro. If + ;; CFD-FUN adds `c-decl-end' properties somewhere below the current + ;; spot, it should return non-nil to ensure that the next search + ;; will find them. + ;; + ;; The spots are visited approximately in order from top to bottom. + ;; It's however the positions where `c-decl-prefix-or-start-re' + ;; matches and where `c-decl-end' properties are found that are in + ;; order. Since the spots often are at the following token, they + ;; might be visited out of order insofar as more spots are reported + ;; later on within the syntactic whitespace between the match + ;; positions and their spots. + ;; + ;; It's assumed that comments and strings are fontified in the ;; searched range. ;; ;; This is mainly used in fontification, and so has an elaborate @@ -3128,19 +3582,28 @@ ;; ;; All variables in this function begin with `cfd-' to avoid name ;; collision with the (dynamically bound) variables used in CFD-FUN. - - (let ((cfd-buffer-end (point-max)) - ;; The last regexp match found by `c-find-decl-prefix-search'. + ;; + ;; This function might do hidden buffer changes. + + (let ((cfd-start-pos (point)) + (cfd-buffer-end (point-max)) + ;; The end of the token preceding the decl spot last found + ;; with `c-decl-prefix-or-start-re'. `cfd-limit' if there's + ;; no match. cfd-re-match - ;; The last `c-decl-end' found by `c-find-decl-prefix-search'. - ;; If searching for the property isn't needed then we disable - ;; it by faking a first match at the limit. + ;; The end position of the last `c-decl-prefix-or-start-re' + ;; match. If this is greater than `cfd-continue-pos', the + ;; next regexp search is started here instead. + (cfd-re-match-end (point-min)) + ;; The end of the last `c-decl-end' found by + ;; `c-find-decl-prefix-search'. `cfd-limit' if there's no + ;; match. If searching for the property isn't needed then we + ;; disable it by setting it to `cfd-limit' directly. (cfd-prop-match (unless c-type-decl-end-used cfd-limit)) - ;; The position of the last match found by - ;; `c-find-decl-prefix-search'. For regexp matches it's the - ;; end of the matched token, for property matches it's the end - ;; of the property. 0 for the implicit match at bob. - ;; `cfd-limit' if there's no match. + ;; The end of the token preceding the decl spot last found by + ;; `c-find-decl-prefix-search'. 0 for the implicit match at + ;; bob. `cfd-limit' if there's no match. In other words, + ;; this is the minimum of `cfd-re-match' and `cfd-prop-match'. (cfd-match-pos cfd-limit) ;; The position to continue searching at. cfd-continue-pos @@ -3153,127 +3616,219 @@ (cfd-macro-end 0)) ;; Initialize by finding a syntactically relevant start position - ;; before the point, and do the first `c-decl-prefix-re' search - ;; unless we're at bob. - - (let ((start-pos (point)) syntactic-pos) + ;; before the point, and do the first `c-decl-prefix-or-start-re' + ;; search unless we're at bob. + + (let (start-in-literal start-in-macro syntactic-pos) ;; Must back up a bit since we look for the end of the previous ;; statement or declaration, which is earlier than the first ;; returned match. - (when (c-got-face-at (point) c-literal-faces) - ;; But first we need to move to a syntactically relevant - ;; position. Use the faces to back up to the start of the - ;; comment or string literal. - (when (and (not (bobp)) - (c-got-face-at (1- (point)) c-literal-faces)) - (while (progn - (goto-char (previous-single-property-change - (point) 'face nil (point-min))) - (and (> (point) (point-min)) - (c-got-face-at (point) c-literal-faces))))) - - ;; XEmacs doesn't fontify the quotes surrounding string - ;; literals. - (and (featurep 'xemacs) - (eq (get-text-property (point) 'face) - 'font-lock-string-face) - (not (bobp)) - (progn (backward-char) - (not (looking-at c-string-limit-regexp))) - (forward-char)) - - ;; The font lock package might not have fontified the start of - ;; the literal at all so check that we have arrived at - ;; something that looks like a start or else resort to - ;; `c-literal-limits'. - (unless (looking-at c-literal-start-regexp) - (let ((range (c-literal-limits))) - (if range (goto-char (car range)))))) - - ;; Must back out of any macro so that we don't miss any - ;; declaration that could follow after it, unless the limit is - ;; inside the macro. We only check that for the current line to - ;; save some time; it's enough for the by far most common case - ;; when font-lock refontifies the current line only. - (when (save-excursion - (and (= (forward-line 1) 0) - (bolp) ; forward-line has funny behavior at eob. - (or (< (c-point 'eol) cfd-limit) - (progn (backward-char) - (not (eq (char-before) ?\\)))))) - (c-beginning-of-macro)) - - ;; Clear the cache if it applied further down. - (c-invalidate-find-decl-cache start-pos) - - (setq syntactic-pos (point)) - (c-backward-syntactic-ws c-find-decl-syntactic-pos) - - ;; If we hit `c-find-decl-syntactic-pos' and - ;; `c-find-decl-match-pos' is set then we install the cached - ;; values. If we hit `c-find-decl-syntactic-pos' and - ;; `c-find-decl-match-pos' is nil then we know there's no decl - ;; prefix in the whitespace before `c-find-decl-syntactic-pos' - ;; and so we can continue the search from this point. If we - ;; didn't hit `c-find-decl-syntactic-pos' then we're now in the - ;; right spot to begin searching anyway. - (if (and (eq (point) c-find-decl-syntactic-pos) - c-find-decl-match-pos) - - (progn - ;; The match is always outside macros and comments so we - ;; start at the next token. The loop below will later go - ;; back using `cfd-continue-pos' to fix declarations inside - ;; the syntactic ws. + (cond + ;; First we need to move to a syntactically relevant position. + ;; Begin by backing out of comment or string literals. + ((and + (when (c-got-face-at (point) c-literal-faces) + ;; Try to use the faces to back up to the start of the + ;; literal. FIXME: What if the point is on a declaration + ;; inside a comment? + (while (and (not (bobp)) + (c-got-face-at (1- (point)) c-literal-faces)) + (goto-char (previous-single-property-change + (point) 'face nil (point-min)))) + + ;; XEmacs doesn't fontify the quotes surrounding string + ;; literals. + (and (featurep 'xemacs) + (eq (get-text-property (point) 'face) + 'font-lock-string-face) + (not (bobp)) + (progn (backward-char) + (not (looking-at c-string-limit-regexp))) + (forward-char)) + + ;; Don't trust the literal to contain only literal faces + ;; (the font lock package might not have fontified the + ;; start of it at all, for instance) so check that we have + ;; arrived at something that looks like a start or else + ;; resort to `c-literal-limits'. + (unless (looking-at c-literal-start-regexp) + (let ((range (c-literal-limits))) + (if range (goto-char (car range))))) + + (setq start-in-literal (point))) + + ;; The start is in a literal. If the limit is in the same + ;; one we don't have to find a syntactic position etc. We + ;; only check that if the limit is at or before bonl to save + ;; time; it covers the by far most common case when font-lock + ;; refontifies the current line only. + (<= cfd-limit (c-point 'bonl cfd-start-pos)) + (save-excursion + (goto-char cfd-start-pos) + (while (progn + (goto-char (next-single-property-change + (point) 'face nil cfd-limit)) + (and (< (point) cfd-limit) + (c-got-face-at (point) c-literal-faces)))) + (= (point) cfd-limit))) + + ;; Completely inside a literal. Set up variables to trig the + ;; (< cfd-continue-pos cfd-start-pos) case below and it'll + ;; find a suitable start position. + (setq cfd-continue-pos start-in-literal)) + + ;; Check if the region might be completely inside a macro, to + ;; optimize that like the completely-inside-literal above. + ((save-excursion + (and (= (forward-line 1) 0) + (bolp) ; forward-line has funny behavior at eob. + (>= (point) cfd-limit) + (progn (backward-char) + (eq (char-before) ?\\)))) + ;; (Maybe) completely inside a macro. Only need to trig the + ;; (< cfd-continue-pos cfd-start-pos) case below to make it + ;; set things up. + (setq cfd-continue-pos (1- cfd-start-pos) + start-in-macro t)) + + (t + ;; Back out of any macro so we don't miss any declaration + ;; that could follow after it. + (when (c-beginning-of-macro) + (setq start-in-macro t)) + + ;; Now we're at a proper syntactically relevant position so we + ;; can use the cache. But first clear it if it applied + ;; further down. + (c-invalidate-find-decl-cache cfd-start-pos) + + (setq syntactic-pos (point)) + (unless (eq syntactic-pos c-find-decl-syntactic-pos) + ;; Don't have to do this if the cache is relevant here, + ;; typically if the same line is refontified again. If + ;; we're just some syntactic whitespace further down we can + ;; still use the cache to limit the skipping. + (c-backward-syntactic-ws c-find-decl-syntactic-pos)) + + ;; If we hit `c-find-decl-syntactic-pos' and + ;; `c-find-decl-match-pos' is set then we install the cached + ;; values. If we hit `c-find-decl-syntactic-pos' and + ;; `c-find-decl-match-pos' is nil then we know there's no decl + ;; prefix in the whitespace before `c-find-decl-syntactic-pos' + ;; and so we can continue the search from this point. If we + ;; didn't hit `c-find-decl-syntactic-pos' then we're now in + ;; the right spot to begin searching anyway. + (if (and (eq (point) c-find-decl-syntactic-pos) + c-find-decl-match-pos) + (setq cfd-match-pos c-find-decl-match-pos + cfd-continue-pos syntactic-pos) + + (setq c-find-decl-syntactic-pos syntactic-pos) + + (when (if (bobp) + ;; Always consider bob a match to get the first + ;; declaration in the file. Do this separately instead of + ;; letting `c-decl-prefix-or-start-re' match bob, so that + ;; regexp always can consume at least one character to + ;; ensure that we won't get stuck in an infinite loop. + (setq cfd-re-match 0) + (backward-char) + (c-beginning-of-current-token) + (< (point) cfd-limit)) + ;; Do an initial search now. In the bob case above it's + ;; only done to search for a `c-decl-end' spot. + (c-find-decl-prefix-search)) + + (setq c-find-decl-match-pos (and (< cfd-match-pos cfd-start-pos) + cfd-match-pos))))) + + ;; Advance `cfd-continue-pos' if it's before the start position. + ;; The closest continue position that might have effect at or + ;; after the start depends on what we started in. This also + ;; finds a suitable start position in the special cases when the + ;; region is completely within a literal or macro. + (when (and cfd-continue-pos (< cfd-continue-pos cfd-start-pos)) + + (cond + (start-in-macro + ;; If we're in a macro then it's the closest preceding token + ;; in the macro. Check this before `start-in-literal', + ;; since if we're inside a literal in a macro, the preceding + ;; token is earlier than any `c-decl-end' spot inside the + ;; literal (comment). + (goto-char (or start-in-literal cfd-start-pos)) + ;; The only syntactic ws in macros are comments. + (c-backward-comments) + (backward-char) + (c-beginning-of-current-token)) + + (start-in-literal + ;; If we're in a comment it can only be the closest + ;; preceding `c-decl-end' position within that comment, if + ;; any. Go back to the beginning of such a property so that + ;; `c-find-decl-prefix-search' will find the end of it. + ;; (Can't stop at the end and install it directly on + ;; `cfd-prop-match' since that variable might be cleared + ;; after `cfd-fun' below.) + ;; + ;; Note that if the literal is a string then the property + ;; search will simply skip to the beginning of it right + ;; away. + (if (not c-type-decl-end-used) + (goto-char start-in-literal) + (goto-char cfd-start-pos) + (while (progn + (goto-char (previous-single-property-change + (point) 'c-type nil start-in-literal)) + (and (> (point) start-in-literal) + (not (eq (c-get-char-property (point) 'c-type) + 'c-decl-end)))))) + + (when (= (point) start-in-literal) + ;; Didn't find any property inside the comment, so we can + ;; skip it entirely. (This won't skip past a string, but + ;; that'll be handled quickly by the next + ;; `c-find-decl-prefix-search' anyway.) + (c-forward-single-comment) + (if (> (point) cfd-limit) + (goto-char cfd-limit)))) + + (t + ;; If we started in normal code, the only match that might + ;; apply before the start is what we already got in + ;; `cfd-match-pos' so we can continue at the start position. + ;; (Note that we don't get here if the first match is below + ;; it.) + (goto-char cfd-start-pos))) + + ;; Delete found matches if they are before our new continue + ;; position, so that `c-find-decl-prefix-search' won't back up + ;; to them later on. + (setq cfd-continue-pos (point)) + (when (and cfd-re-match (< cfd-re-match cfd-continue-pos)) + (setq cfd-re-match nil)) + (when (and cfd-prop-match (< cfd-prop-match cfd-continue-pos)) + (setq cfd-prop-match nil))) + + (if syntactic-pos + ;; This is the normal case and we got a proper syntactic + ;; position. If there's a match then it's always outside + ;; macros and comments, so advance to the next token and set + ;; `cfd-token-pos'. The loop below will later go back using + ;; `cfd-continue-pos' to fix declarations inside the + ;; syntactic ws. + (when (and cfd-match-pos (< cfd-match-pos syntactic-pos)) (goto-char syntactic-pos) (c-forward-syntactic-ws) - (setq cfd-match-pos c-find-decl-match-pos - cfd-continue-pos syntactic-pos) - (if (< cfd-continue-pos (point)) - (setq cfd-token-pos (point)))) - - (setq c-find-decl-syntactic-pos syntactic-pos) - - (when (if (bobp) - ;; Always consider bob a match to get the first declaration - ;; in the file. Do this separately instead of letting - ;; `c-decl-prefix-re' match bob, so that it always can - ;; consume at least one character to ensure that we won't - ;; get stuck in an infinite loop. - (setq cfd-re-match 0) - (backward-char) - (c-beginning-of-current-token) - (< (point) cfd-limit)) - ;; Do an initial search now. In the bob case above it's only done - ;; to search for the `c-type' property. - (c-find-decl-prefix-search)) - - ;; Advance `cfd-continue-pos' if we got a hit before the start - ;; position. The earliest position that could affect after - ;; the start position is the char before the preceding - ;; comments. - (when (and cfd-continue-pos (< cfd-continue-pos start-pos)) - (goto-char syntactic-pos) - (c-backward-comments) - (unless (bobp) - (backward-char) - (c-beginning-of-current-token)) - (setq cfd-continue-pos (max cfd-continue-pos (point)))) - - ;; If we got a match it's always outside macros and comments so - ;; advance to the next token and set `cfd-token-pos'. The loop - ;; below will later go back using `cfd-continue-pos' to fix - ;; declarations inside the syntactic ws. - (when (and (< cfd-match-pos cfd-limit) (< (point) syntactic-pos)) - (goto-char syntactic-pos) - (c-forward-syntactic-ws) - (and cfd-continue-pos - (< cfd-continue-pos (point)) - (setq cfd-token-pos (point)))) - - (setq c-find-decl-match-pos (and (< cfd-match-pos start-pos) - cfd-match-pos)))) + (and cfd-continue-pos + (< cfd-continue-pos (point)) + (setq cfd-token-pos (point)))) + + ;; Have one of the special cases when the region is completely + ;; within a literal or macro. `cfd-continue-pos' is set to a + ;; good start position for the search, so do it. + (c-find-decl-prefix-search))) ;; Now loop. We already got the first match. @@ -3323,33 +3878,37 @@ (< (point) cfd-limit)) - (when (progn - ;; Narrow to the end of the macro if we got a hit inside - ;; one, to avoid recognizing things that start inside - ;; the macro and end outside it. - (when (> cfd-match-pos cfd-macro-end) - ;; Not in the same macro as in the previous round. - (save-excursion - (goto-char cfd-match-pos) - (setq cfd-macro-end - (if (save-excursion (and (c-beginning-of-macro) - (< (point) cfd-match-pos))) - (progn (c-end-of-macro) - (point)) - 0)))) - - (if (zerop cfd-macro-end) - t - (if (> cfd-macro-end (point)) - (progn (narrow-to-region (point-min) cfd-macro-end) - t) - ;; The matched token was the last thing in the - ;; macro, so the whole match is bogus. - (setq cfd-macro-end 0) - nil))) + (when (and + (>= (point) cfd-start-pos) + + (progn + ;; Narrow to the end of the macro if we got a hit inside + ;; one, to avoid recognizing things that start inside the + ;; macro and end outside it. + (when (> cfd-match-pos cfd-macro-end) + ;; Not in the same macro as in the previous round. + (save-excursion + (goto-char cfd-match-pos) + (setq cfd-macro-end + (if (save-excursion (and (c-beginning-of-macro) + (< (point) cfd-match-pos))) + (progn (c-end-of-macro) + (point)) + 0)))) + + (if (zerop cfd-macro-end) + t + (if (> cfd-macro-end (point)) + (progn (narrow-to-region (point-min) cfd-macro-end) + t) + ;; The matched token was the last thing in the macro, + ;; so the whole match is bogus. + (setq cfd-macro-end 0) + nil)))) (c-debug-put-decl-spot-faces cfd-match-pos (point)) - (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0)) + (if (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0)) + (setq cfd-prop-match nil)) (when (/= cfd-macro-end 0) ;; Restore limits if we did macro narrowment above. @@ -3370,14 +3929,23 @@ ;; bother with the scoping rules of the languages, but in practice the ;; same name is seldom used as both a type and something else in a ;; file, and we only use this as a last resort in ambiguous cases (see -;; `c-font-lock-declarations'). +;; `c-forward-decl-or-cast-1'). +;; +;; Template types in C++ are added here too but with the template +;; arglist replaced with "<>" in references or "<" for the one in the +;; primary type. E.g. the type "Foo::Bar" is stored as +;; "Foo<>::Bar<". This avoids storing very long strings (since C++ +;; template specs can be fairly sized programs in themselves) and +;; improves the hit ratio (it's a type regardless of the template +;; args; it's just not the same type, but we're only interested in +;; recognizing types, not telling distinct types apart). Note that +;; template types in references are added here too; from the example +;; above there will also be an entry "Foo<". (defvar c-found-types nil) (make-variable-buffer-local 'c-found-types) (defsubst c-clear-found-types () ;; Clears `c-found-types'. - ;; - ;; This function does not do any hidden buffer changes. (setq c-found-types (make-vector 53 0))) (defun c-add-type (from to) @@ -3389,23 +3957,20 @@ ;; doesn't cover cases like when characters are removed from a type ;; or added in the middle. We'd need the position of point when the ;; font locking is invoked to solve this well. - (unless (and c-recognize-<>-arglists - (save-excursion - (goto-char from) - (c-syntactic-re-search-forward "<" to t))) - ;; To avoid storing very long strings, do not add a type that - ;; contains '<' in languages with angle bracket arglists, since - ;; the type then probably contains a C++ template spec and those - ;; can be fairly sized programs in themselves. - (let ((type (c-syntactic-content from to))) - (unless (intern-soft type c-found-types) - (unintern (substring type 0 -1) c-found-types) - (intern type c-found-types))))) + ;; + ;; This function might do hidden buffer changes. + (let ((type (c-syntactic-content from to c-recognize-<>-arglists))) + (unless (intern-soft type c-found-types) + (unintern (substring type 0 -1) c-found-types) + (intern type c-found-types)))) (defsubst c-check-type (from to) ;; Return non-nil if the given region contains a type in ;; `c-found-types'. - (intern-soft (c-syntactic-content from to) c-found-types)) + ;; + ;; This function might do hidden buffer changes. + (intern-soft (c-syntactic-content from to c-recognize-<>-arglists) + c-found-types)) (defun c-list-found-types () ;; Return all the types in `c-found-types' as a sorted list of @@ -3420,17 +3985,43 @@ ;; Handling of small scale constructs like types and names. -(defun c-remove-<>-arglist-properties (from to) - ;; Remove all the properties put by `c-forward-<>-arglist' in the - ;; specified region. Point is clobbered. - (goto-char from) - (while (progn (skip-chars-forward "^<>," to) - (< (point) to)) - (if (eq (char-after) ?,) - (when (eq (c-get-char-property (point) 'c-type) 'c-<>-arg-sep) - (c-clear-char-property (point) 'c-type)) - (c-clear-char-property (point) 'syntax-table)) - (forward-char))) +(defun c-after-change-check-<>-operators (beg end) + ;; This is called from `after-change-functions' when + ;; c-recognize-<>-arglists' is set. It ensures that no "<" or ">" + ;; chars with paren syntax become part of another operator like "<<" + ;; or ">=". + ;; + ;; This function might do hidden buffer changes. + + (save-excursion + (goto-char beg) + (when (or (looking-at "[<>]") + (< (skip-chars-backward "<>") 0)) + + (goto-char beg) + (c-beginning-of-current-token) + (when (and (< (point) beg) + (looking-at c-<>-multichar-token-regexp) + (< beg (setq beg (match-end 0)))) + (while (progn (skip-chars-forward "^<>" beg) + (< (point) beg)) + (c-clear-char-property (point) 'syntax-table) + (forward-char)))) + + (when (< beg end) + (goto-char end) + (when (or (looking-at "[<>]") + (< (skip-chars-backward "<>") 0)) + + (goto-char end) + (c-beginning-of-current-token) + (when (and (< (point) end) + (looking-at c-<>-multichar-token-regexp) + (< end (setq end (match-end 0)))) + (while (progn (skip-chars-forward "^<>" end) + (< (point) end)) + (c-clear-char-property (point) 'syntax-table) + (forward-char))))))) ;; Dynamically bound variable that instructs `c-forward-type' to also ;; treat possible types (i.e. those that it normally returns 'maybe or @@ -3440,6 +4031,20 @@ (defvar c-promote-possible-types nil) ;; Dynamically bound variable that instructs `c-forward-<>-arglist' to +;; mark up successfully parsed arglists with paren syntax properties on +;; the surrounding angle brackets and with `c-<>-arg-sep' in the +;; `c-type' property of each argument separating comma. +;; +;; Setting this variable also makes `c-forward-<>-arglist' recurse into +;; all arglists for side effects (i.e. recording types), otherwise it +;; exploits any existing paren syntax properties to quickly jump to the +;; end of already parsed arglists. +;; +;; Marking up the arglists is not the default since doing that correctly +;; depends on a proper value for `c-restricted-<>-arglists'. +(defvar c-parse-and-markup-<>-arglists nil) + +;; Dynamically bound variable that instructs `c-forward-<>-arglist' to ;; not accept arglists that contain binary operators. ;; ;; This is primarily used to handle C++ template arglists. C++ @@ -3455,31 +4060,36 @@ ;; "if (a < b || c > d)", it's probably not a template. (defvar c-restricted-<>-arglists nil) -;; Dynamically bound variables that instructs `c-forward-name', -;; `c-forward-type' and `c-forward-<>-arglist' to record the ranges of -;; all the type and reference identifiers they encounter. They will -;; build lists on these variables where each element is a cons of the -;; buffer positions surrounding each identifier. This recording is -;; only activated when `c-record-type-identifiers' is non-nil. +;; Dynamically bound variables that instructs +;; `c-forward-keyword-clause', `c-forward-<>-arglist', +;; `c-forward-name', `c-forward-type', `c-forward-decl-or-cast-1', and +;; `c-forward-label' to record the ranges of all the type and +;; reference identifiers they encounter. They will build lists on +;; these variables where each element is a cons of the buffer +;; positions surrounding each identifier. This recording is only +;; activated when `c-record-type-identifiers' is non-nil. ;; ;; All known types that can't be identifiers are recorded, and also ;; other possible types if `c-promote-possible-types' is set. ;; Recording is however disabled inside angle bracket arglists that ;; are encountered inside names and other angle bracket arglists. -;; Such occurences are taken care of by `c-font-lock-<>-arglists' +;; Such occurrences are taken care of by `c-font-lock-<>-arglists' ;; instead. ;; ;; Only the names in C++ template style references (e.g. "tmpl" in ;; "tmpl::foo") are recorded as references, other references ;; aren't handled here. +;; +;; `c-forward-label' records the label identifier(s) on +;; `c-record-ref-identifiers'. (defvar c-record-type-identifiers nil) (defvar c-record-ref-identifiers nil) -;; If `c-record-type-identifiers' is set, this will receive a cons -;; cell of the range of the last single identifier symbol stepped over -;; by `c-forward-name' if it's successful. This is the range that -;; should be put on one of the record lists by the caller. It's -;; assigned nil if there's no such symbol in the name. +;; This variable will receive a cons cell of the range of the last +;; single identifier symbol stepped over by `c-forward-name' if it's +;; successful. This is the range that should be put on one of the +;; record lists above by the caller. It's assigned nil if there's no +;; such symbol in the name. (defvar c-last-identifier-range nil) (defmacro c-record-type-id (range) @@ -3516,45 +4126,70 @@ ;; over. The point is clobbered if nil is returned. If range ;; recording is enabled, the identifier is recorded on as a type ;; if TYPE is 'type or as a reference if TYPE is 'ref. + ;; + ;; This macro might do hidden buffer changes. `(let (res) (while (if (setq res ,(if (eq type 'type) `(c-forward-type) `(c-forward-name))) nil (and (looking-at c-keywords-regexp) - (c-forward-keyword-clause)))) + (c-forward-keyword-clause 1)))) (when (memq res '(t known found prefix)) ,(when (eq type 'ref) `(when c-record-type-identifiers (c-record-ref-id c-last-identifier-range))) t))) -(defmacro c-forward-id-comma-list (type) +(defmacro c-forward-id-comma-list (type update-safe-pos) ;; Used internally in `c-forward-keyword-clause' to move forward ;; over a comma separated list of types or names using ;; `c-forward-keyword-prefixed-id'. + ;; + ;; This macro might do hidden buffer changes. `(while (and (progn - (setq safe-pos (point)) + ,(when update-safe-pos + `(setq safe-pos (point))) (eq (char-after) ?,)) (progn (forward-char) (c-forward-syntactic-ws) (c-forward-keyword-prefixed-id ,type))))) -(defun c-forward-keyword-clause () - ;; The first submatch in the current match data is assumed to - ;; surround a token. If it's a keyword, move over it and any - ;; following clauses associated with it, stopping at the next - ;; following token. t is returned in that case, otherwise the point +(defun c-forward-keyword-clause (match) + ;; Submatch MATCH in the current match data is assumed to surround a + ;; token. If it's a keyword, move over it and any immediately + ;; following clauses associated with it, stopping at the start of + ;; the next token. t is returned in that case, otherwise the point ;; stays and nil is returned. The kind of clauses that are ;; recognized are those specified by `c-type-list-kwds', ;; `c-ref-list-kwds', `c-colon-type-list-kwds', ;; `c-paren-nontype-kwds', `c-paren-type-kwds', `c-<>-type-kwds', ;; and `c-<>-arglist-kwds'. - - (let ((kwd-sym (c-keyword-sym (match-string 1))) safe-pos pos) + ;; + ;; This function records identifier ranges on + ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if + ;; `c-record-type-identifiers' is non-nil. + ;; + ;; Note that for `c-colon-type-list-kwds', which doesn't necessary + ;; apply directly after the keyword, the type list is moved over + ;; only when there is no unaccounted token before it (i.e. a token + ;; that isn't moved over due to some other keyword list). The + ;; identifier ranges in the list are still recorded if that should + ;; be done, though. + ;; + ;; This function might do hidden buffer changes. + + (let ((kwd-sym (c-keyword-sym (match-string match))) safe-pos pos + ;; The call to `c-forward-<>-arglist' below is made after + ;; `c-<>-sexp-kwds' keywords, so we're certain they actually + ;; are angle bracket arglists and `c-restricted-<>-arglists' + ;; should therefore be nil. + (c-parse-and-markup-<>-arglists t) + c-restricted-<>-arglists) + (when kwd-sym - (goto-char (match-end 1)) + (goto-char (match-end match)) (c-forward-syntactic-ws) (setq safe-pos (point)) @@ -3562,12 +4197,12 @@ ((and (c-keyword-member kwd-sym 'c-type-list-kwds) (c-forward-keyword-prefixed-id type)) ;; There's a type directly after a keyword in `c-type-list-kwds'. - (c-forward-id-comma-list type)) + (c-forward-id-comma-list type t)) ((and (c-keyword-member kwd-sym 'c-ref-list-kwds) (c-forward-keyword-prefixed-id ref)) ;; There's a name directly after a keyword in `c-ref-list-kwds'. - (c-forward-id-comma-list ref)) + (c-forward-id-comma-list ref t)) ((and (c-keyword-member kwd-sym 'c-paren-any-kwds) (eq (char-after) ?\()) @@ -3592,9 +4227,7 @@ ((and (c-keyword-member kwd-sym 'c-<>-sexp-kwds) (eq (char-after) ?<) - (c-forward-<>-arglist (c-keyword-member kwd-sym 'c-<>-type-kwds) - (or c-record-type-identifiers - c-restricted-<>-arglists))) + (c-forward-<>-arglist (c-keyword-member kwd-sym 'c-<>-type-kwds))) (c-forward-syntactic-ws) (setq safe-pos (point))) @@ -3604,46 +4237,56 @@ (c-forward-syntactic-ws) (setq safe-pos (point)))) - (when (and (c-keyword-member kwd-sym 'c-colon-type-list-kwds) - (progn - ;; If a keyword matched both one of the types above and - ;; this one, we match `c-colon-type-list-re' after the - ;; clause matched above. - (goto-char safe-pos) - (looking-at c-colon-type-list-re)) - (progn - (goto-char (match-end 0)) - (c-forward-syntactic-ws) - (c-forward-keyword-prefixed-id type))) - ;; There's a type after the `c-colon-type-list-re' - ;; match after a keyword in `c-colon-type-list-kwds'. - (c-forward-id-comma-list type)) + (when (c-keyword-member kwd-sym 'c-colon-type-list-kwds) + (if (eq (char-after) ?:) + ;; If we are at the colon already, we move over the type + ;; list after it. + (progn + (forward-char) + (c-forward-syntactic-ws) + (when (c-forward-keyword-prefixed-id type) + (c-forward-id-comma-list type t))) + ;; Not at the colon, so stop here. But the identifier + ;; ranges in the type list later on should still be + ;; recorded. + (and c-record-type-identifiers + (progn + ;; If a keyword matched both one of the types above and + ;; this one, we match `c-colon-type-list-re' after the + ;; clause matched above. + (goto-char safe-pos) + (looking-at c-colon-type-list-re)) + (progn + (goto-char (match-end 0)) + (c-forward-syntactic-ws) + (c-forward-keyword-prefixed-id type)) + ;; There's a type after the `c-colon-type-list-re' match + ;; after a keyword in `c-colon-type-list-kwds'. + (c-forward-id-comma-list type nil)))) (goto-char safe-pos) t))) -(defun c-forward-<>-arglist (all-types reparse) - ;; The point is assumed to be at a '<'. Try to treat it as the open +(defun c-forward-<>-arglist (all-types) + ;; The point is assumed to be at a "<". Try to treat it as the open ;; paren of an angle bracket arglist and move forward to the the - ;; corresponding '>'. If successful, the point is left after the - ;; '>' and t is returned, otherwise the point isn't moved and nil is + ;; corresponding ">". If successful, the point is left after the + ;; ">" and t is returned, otherwise the point isn't moved and nil is ;; returned. If ALL-TYPES is t then all encountered arguments in ;; the arglist that might be types are treated as found types. ;; - ;; The surrounding '<' and '>' are given syntax-table properties to - ;; make them behave like parentheses. Each argument separating ',' - ;; is also set to `c-<>-arg-sep' in the `c-type' property. These - ;; properties are also cleared in a relevant region forward from the - ;; point if they seems to be set and it turns out to not be an - ;; arglist. - ;; - ;; If the arglist has been successfully parsed before then paren - ;; syntax properties will be exploited to quickly jump to the end, - ;; but that can be disabled by setting REPARSE to t. That is - ;; necessary if the various side effects, e.g. recording of type - ;; ranges, are important. Setting REPARSE to t only applies - ;; recursively to nested angle bracket arglists if - ;; `c-restricted-<>-arglists' is set. + ;; The variable `c-parse-and-markup-<>-arglists' controls how this + ;; function handles text properties on the angle brackets and argument + ;; separating commas. + ;; + ;; `c-restricted-<>-arglists' controls how lenient the template + ;; arglist recognition should be. + ;; + ;; This function records identifier ranges on + ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if + ;; `c-record-type-identifiers' is non-nil. + ;; + ;; This function might do hidden buffer changes. (let ((start (point)) ;; If `c-record-type-identifiers' is set then activate @@ -3652,7 +4295,7 @@ (c-record-found-types (if c-record-type-identifiers t))) (if (catch 'angle-bracket-arglist-escape (setq c-record-found-types - (c-forward-<>-arglist-recur all-types reparse))) + (c-forward-<>-arglist-recur all-types))) (progn (when (consp c-record-found-types) (setq c-record-type-identifiers @@ -3664,8 +4307,10 @@ (goto-char start) nil))) -(defun c-forward-<>-arglist-recur (all-types reparse) +(defun c-forward-<>-arglist-recur (all-types) ;; Recursive part of `c-forward-<>-arglist'. + ;; + ;; This function might do hidden buffer changes. (let ((start (point)) res pos tmp ;; Cover this so that any recorded found type ranges are @@ -3677,61 +4322,24 @@ ;; separating ',' in the arglist. arg-start-pos) - ;; If the '<' has paren open syntax then we've marked it as an - ;; angle bracket arglist before, so try to skip to the end and see - ;; that the close paren matches. - (if (and (c-get-char-property (point) 'syntax-table) - (progn - (forward-char) - (if (and (not (looking-at c-<-op-cont-regexp)) - (if (c-parse-sexp-lookup-properties) - (c-go-up-list-forward) - (catch 'at-end - (let ((depth 1)) - (while (c-syntactic-re-search-forward - "[<>]" nil t t) - (when (c-get-char-property (1- (point)) - 'syntax-table) - (if (eq (char-before) ?<) - (setq depth (1+ depth)) - (setq depth (1- depth)) - (when (= depth 0) (throw 'at-end t))))) - nil))) - (not (looking-at c->-op-cont-regexp)) - (save-excursion - (backward-char) - (= (point) - (progn (c-beginning-of-current-token) - (point))))) - - ;; Got an arglist that appears to be valid. - (if reparse - ;; Reparsing is requested, so zap the properties in the - ;; region and go on to redo it. It's done here to - ;; avoid leaving it behind if we exit through - ;; `angle-bracket-arglist-escape' below. - (progn - (c-remove-<>-arglist-properties start (point)) - (goto-char start) - nil) - t) - - ;; Got unmatched paren brackets or either paren was - ;; actually some other token. Recover by clearing the - ;; syntax properties on all the '<' and '>' in the - ;; range where we'll search for the arglist below. - (goto-char start) - (while (progn (skip-chars-forward "^<>,;{}") - (looking-at "[<>,]")) - (if (eq (char-after) ?,) - (when (eq (c-get-char-property (point) 'c-type) - 'c-<>-arg-sep) - (c-clear-char-property (point) 'c-type)) - (c-clear-char-property (point) 'syntax-table)) - (forward-char)) - (goto-char start) - nil))) - t + ;; If the '<' has paren open syntax then we've marked it as an angle + ;; bracket arglist before, so skip to the end. + (if (and (not c-parse-and-markup-<>-arglists) + (c-get-char-property (point) 'syntax-table)) + + (progn + (forward-char) + (if (and (c-go-up-list-forward) + (eq (char-before) ?>)) + t + + ;; Got unmatched paren angle brackets. We don't clear the paren + ;; syntax properties and retry, on the basis that it's very + ;; unlikely that paren angle brackets become operators by code + ;; manipulation. It's far more likely that it doesn't match due + ;; to narrowing or some temporary change. + (goto-char start) + nil)) (forward-char) (unless (looking-at c-<-op-cont-regexp) @@ -3793,11 +4401,6 @@ ;; balanced sexp. In that case we stop just short ;; of it so check if the following char is the closer. (when (eq (char-after) ?>) - ;; Remove its syntax so that we don't enter the - ;; recovery code below. That's not necessary - ;; since there's no real reason to suspect that - ;; things inside the arglist are unbalanced. - (c-clear-char-property (point) 'syntax-table) (forward-char) t))) @@ -3806,40 +4409,21 @@ ;; Either an operator starting with '>' or the end of ;; the angle bracket arglist. - (if (and (/= (1- (point)) pos) - (c-get-char-property (1- (point)) 'syntax-table) - (progn - (c-clear-char-property (1- (point)) 'syntax-table) - (c-parse-sexp-lookup-properties))) - - ;; We've skipped past a list that ended with '>'. It - ;; must be unbalanced since nested arglists are handled - ;; in the case below. Recover by removing all paren - ;; properties on '<' and '>' in the searched region and - ;; redo the search. + (if (looking-at c->-op-cont-regexp) (progn - (c-remove-<>-arglist-properties pos (point)) - (goto-char pos) - t) - - (if (looking-at c->-op-cont-regexp) - (progn - (when (text-property-not-all - (1- (point)) (match-end 0) 'syntax-table nil) - (c-remove-<>-arglist-properties (1- (point)) - (match-end 0))) - (goto-char (match-end 0)) - t) - - ;; The angle bracket arglist is finished. + (goto-char (match-end 0)) + t) ; Continue the loop. + + ;; The angle bracket arglist is finished. + (when c-parse-and-markup-<>-arglists (while arg-start-pos - (c-put-char-property (1- (car arg-start-pos)) - 'c-type 'c-<>-arg-sep) + (c-put-c-type-property (1- (car arg-start-pos)) + 'c-<>-arg-sep) (setq arg-start-pos (cdr arg-start-pos))) (c-mark-<-as-paren start) - (c-mark->-as-paren (1- (point))) - (setq res t) - nil))) + (c-mark->-as-paren (1- (point)))) + (setq res t) + nil)) ; Exit the loop. ((eq (char-before) ?<) ;; Either an operator starting with '<' or a nested arglist. @@ -3854,7 +4438,7 @@ (and (save-excursion - ;; There's always an identifier before a angle + ;; There's always an identifier before an angle ;; bracket arglist, or a keyword in ;; `c-<>-type-kwds' or `c-<>-arglist-kwds'. (c-backward-syntactic-ws) @@ -3872,26 +4456,11 @@ (and keyword-match (c-keyword-member (c-keyword-sym (match-string 1)) - 'c-<>-type-kwds)) - (and reparse - c-restricted-<>-arglists)))) + 'c-<>-type-kwds))))) ))) ;; It was not an angle bracket arglist. - (progn - (when (text-property-not-all - (1- pos) tmp 'syntax-table nil) - (if (c-parse-sexp-lookup-properties) - ;; Got an invalid open paren syntax on this - ;; '<'. We'll probably get an unbalanced '>' - ;; further ahead if we just remove the syntax - ;; here, so recover by removing all paren - ;; properties up to and including the - ;; balancing close paren. - (parse-partial-sexp pos (point-max) -1) - (goto-char tmp)) - (c-remove-<>-arglist-properties pos (point))) - (goto-char tmp)) + (goto-char tmp) ;; It was an angle bracket arglist. (setq c-record-found-types subres) @@ -3926,6 +4495,70 @@ (if res (or c-record-found-types t))))) +(defun c-backward-<>-arglist (all-types &optional limit) + ;; The point is assumed to be directly after a ">". Try to treat it + ;; as the close paren of an angle bracket arglist and move back to + ;; the corresponding "<". If successful, the point is left at + ;; the "<" and t is returned, otherwise the point isn't moved and + ;; nil is returned. ALL-TYPES is passed on to + ;; `c-forward-<>-arglist'. + ;; + ;; If the optional LIMIT is given, it bounds the backward search. + ;; It's then assumed to be at a syntactically relevant position. + ;; + ;; This is a wrapper around `c-forward-<>-arglist'. See that + ;; function for more details. + + (let ((start (point))) + (backward-char) + (if (and (not c-parse-and-markup-<>-arglists) + (c-get-char-property (point) 'syntax-table)) + + (if (and (c-go-up-list-backward) + (eq (char-after) ?<)) + t + ;; See corresponding note in `c-forward-<>-arglist'. + (goto-char start) + nil) + + (while (and + (c-syntactic-skip-backward "^<;{}" limit t) + + (if (eq (char-before) ?<) + t + ;; Stopped at bob or a char that isn't allowed in an + ;; arglist, so we've failed. + (goto-char start) + nil) + + (if (> (point) + (progn (c-beginning-of-current-token) + (point))) + ;; If we moved then the "<" was part of some + ;; multicharacter token. + t + + (backward-char) + (let ((beg-pos (point))) + (if (c-forward-<>-arglist all-types) + (cond ((= (point) start) + ;; Matched the arglist. Break the while. + (goto-char beg-pos) + nil) + ((> (point) start) + ;; We started from a non-paren ">" inside an + ;; arglist. + (goto-char start) + nil) + (t + ;; Matched a shorter arglist. Can be a nested + ;; one so continue looking. + (goto-char beg-pos) + t)) + t))))) + + (/= (point) start)))) + (defun c-forward-name () ;; Move forward over a complete name if at the beginning of one, ;; stopping at the next following token. If the point is not at @@ -3939,8 +4572,14 @@ ;; name is found, 'template if it's an identifier ending with an ;; angle bracket arglist, 'operator of it's an operator identifier, ;; or t if it's some other kind of name. - - (let ((pos (point)) res id-start id-end + ;; + ;; This function records identifier ranges on + ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if + ;; `c-record-type-identifiers' is non-nil. + ;; + ;; This function might do hidden buffer changes. + + (let ((pos (point)) (start (point)) res id-start id-end ;; Turn off `c-promote-possible-types' here since we might ;; call `c-forward-<>-arglist' and we don't want it to promote ;; every suspect thing in the arglist to a type. We're @@ -3955,12 +4594,9 @@ (progn ;; Check for keyword. We go to the last symbol in ;; `c-identifier-key' first. - (if (eq c-identifier-key c-symbol-key) - (setq id-start (point) - id-end (match-end 0)) - (goto-char (setq id-end (match-end 0))) - (c-simple-skip-symbol-backward) - (setq id-start (point))) + (goto-char (setq id-end (match-end 0))) + (c-simple-skip-symbol-backward) + (setq id-start (point)) (if (looking-at c-keywords-regexp) (when (and (c-major-mode-is 'c++-mode) @@ -4018,9 +4654,8 @@ ((looking-at c-overloadable-operators-regexp) ;; Got some other operator. - (when c-record-type-identifiers - (setq c-last-identifier-range - (cons (point) (match-end 0)))) + (setq c-last-identifier-range + (cons (point) (match-end 0))) (goto-char (match-end 0)) (c-forward-syntactic-ws) (setq pos (point) @@ -4028,7 +4663,11 @@ nil) - (when c-record-type-identifiers + ;; `id-start' is equal to `id-end' if we've jumped over + ;; an identifier that doesn't end with a symbol token. + ;; That can occur e.g. for Java import directives on the + ;; form "foo.bar.*". + (when (and id-start (/= id-start id-end)) (setq c-last-identifier-range (cons id-start id-end))) (goto-char id-end) @@ -4054,29 +4693,30 @@ ((and c-recognize-<>-arglists (eq (char-after) ?<)) ;; Maybe an angle bracket arglist. - (when (let ((c-record-type-identifiers nil) - (c-record-found-types nil)) - (c-forward-<>-arglist - nil c-restricted-<>-arglists)) + + (when (let (c-record-type-identifiers + c-record-found-types) + (c-forward-<>-arglist nil)) + + (c-add-type start (1+ pos)) (c-forward-syntactic-ws) - (setq pos (point)) + (setq pos (point) + c-last-identifier-range nil) + (if (and c-opt-identifier-concat-key (looking-at c-opt-identifier-concat-key)) + ;; Continue if there's an identifier concatenation ;; operator after the template argument. (progn - (when c-record-type-identifiers - (c-record-ref-id (cons id-start id-end)) - (setq c-last-identifier-range nil)) + (when (and c-record-type-identifiers id-start) + (c-record-ref-id (cons id-start id-end))) (forward-char 2) (c-forward-syntactic-ws) t) - ;; `c-add-type' isn't called here since we don't - ;; want to add types containing angle bracket - ;; arglists. - (when c-record-type-identifiers - (c-record-type-id (cons id-start id-end)) - (setq c-last-identifier-range nil)) + + (when (and c-record-type-identifiers id-start) + (c-record-type-id (cons id-start id-end))) (setq res 'template) nil))) ))))) @@ -4098,7 +4738,14 @@ ;; Note that this function doesn't skip past the brace definition ;; that might be considered part of the type, e.g. ;; "enum {a, b, c} foo". - (let ((start (point)) pos res res2 id-start id-end id-range) + ;; + ;; This function records identifier ranges on + ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if + ;; `c-record-type-identifiers' is non-nil. + ;; + ;; This function might do hidden buffer changes. + + (let ((start (point)) pos res name-res id-start id-end id-range) ;; Skip leading type modifiers. If any are found we know it's a ;; prefix of a type. @@ -4115,13 +4762,14 @@ (goto-char (match-end 1)) (c-forward-syntactic-ws) (setq pos (point)) - (if (memq (setq res2 (c-forward-name)) '(t template)) + (if (memq (setq name-res (c-forward-name)) '(t template)) (progn - (when (eq res2 t) + (when (eq name-res t) ;; In many languages the name can be used without the ;; prefix, so we add it to `c-found-types'. (c-add-type pos (point)) - (when c-record-type-identifiers + (when (and c-record-type-identifiers + c-last-identifier-range) (c-record-type-id c-last-identifier-range))) (setq res t)) ;; Invalid syntax. @@ -4133,8 +4781,8 @@ (if (looking-at c-identifier-start) (save-excursion (setq id-start (point) - res2 (c-forward-name)) - (when res2 + name-res (c-forward-name)) + (when name-res (setq id-end (point) id-range c-last-identifier-range)))) (and (cond ((looking-at c-primitive-type-key) @@ -4165,7 +4813,7 @@ (looking-at c-opt-type-component-key))) ;; There might be more keywords for the type. (let (safe-pos) - (c-forward-keyword-clause) + (c-forward-keyword-clause 1) (while (progn (setq safe-pos (point)) (looking-at c-opt-type-component-key)) @@ -4173,30 +4821,30 @@ (looking-at c-primitive-type-key)) (c-record-type-id (cons (match-beginning 1) (match-end 1)))) - (c-forward-keyword-clause)) + (c-forward-keyword-clause 1)) (if (looking-at c-primitive-type-key) (progn (when c-record-type-identifiers (c-record-type-id (cons (match-beginning 1) (match-end 1)))) - (c-forward-keyword-clause) + (c-forward-keyword-clause 1) (setq res t)) (goto-char safe-pos) (setq res 'prefix))) - (unless (save-match-data (c-forward-keyword-clause)) + (unless (save-match-data (c-forward-keyword-clause 1)) (if pos (goto-char pos) (goto-char (match-end 1)) (c-forward-syntactic-ws))))) - (res2 - (cond ((eq res2 t) + (name-res + (cond ((eq name-res t) ;; A normal identifier. (goto-char id-end) (if (or res c-promote-possible-types) (progn (c-add-type id-start id-end) - (when c-record-type-identifiers + (when (and c-record-type-identifiers id-range) (c-record-type-id id-range)) (unless res (setq res 'found))) @@ -4206,7 +4854,7 @@ 'found ;; It's an identifier that might be a type. 'maybe)))) - ((eq res2 'template) + ((eq name-res 'template) ;; A template is a type. (goto-char id-end) (setq res t)) @@ -4234,9 +4882,11 @@ (c-forward-syntactic-ws))) (when c-opt-type-concat-key - ;; Look for a trailing operator that concatenate the type with - ;; a following one, and if so step past that one through a - ;; recursive call. + ;; Look for a trailing operator that concatenates the type + ;; with a following one, and if so step past that one through + ;; a recursive call. Note that we don't record concatenated + ;; types in `c-found-types' - it's the component types that + ;; are recorded when appropriate. (setq pos (point)) (let* ((c-promote-possible-types (or (memq res '(t known)) c-promote-possible-types)) @@ -4244,29 +4894,31 @@ ;; we can merge in the types from the second part afterwards if ;; it turns out to be a known type there. (c-record-found-types (and c-record-type-identifiers - (not c-promote-possible-types)))) + (not c-promote-possible-types))) + subres) (if (and (looking-at c-opt-type-concat-key) (progn (goto-char (match-end 1)) (c-forward-syntactic-ws) - (setq res2 (c-forward-type)))) + (setq subres (c-forward-type)))) (progn ;; If either operand certainly is a type then both are, but we ;; don't let the existence of the operator itself promote two ;; uncertain types to a certain one. (cond ((eq res t)) - ((eq res2 t) - (c-add-type id-start id-end) - (when c-record-type-identifiers + ((eq subres t) + (unless (eq name-res 'template) + (c-add-type id-start id-end)) + (when (and c-record-type-identifiers id-range) (c-record-type-id id-range)) (setq res t)) ((eq res 'known)) - ((eq res2 'known) + ((eq subres 'known) (setq res 'known)) ((eq res 'found)) - ((eq res2 'found) + ((eq subres 'found) (setq res 'found)) (t (setq res 'maybe))) @@ -4294,23 +4946,1099 @@ ;; Handling of large scale constructs like statements and declarations. +;; Macro used inside `c-forward-decl-or-cast-1'. It ought to be a +;; defsubst or perhaps even a defun, but it contains lots of free +;; variables that refer to things inside `c-forward-decl-or-cast-1'. +(defmacro c-fdoc-shift-type-backward (&optional short) + ;; `c-forward-decl-or-cast-1' can consume an arbitrary length list + ;; of types when parsing a declaration, which means that it + ;; sometimes consumes the identifier in the declaration as a type. + ;; This is used to "backtrack" and make the last type be treated as + ;; an identifier instead. + `(progn + ,(unless short + ;; These identifiers are bound only in the inner let. + '(setq identifier-type at-type + identifier-start type-start + got-parens nil + got-identifier t + got-suffix t + got-suffix-after-parens id-start + paren-depth 0)) + + (if (setq at-type (if (eq backup-at-type 'prefix) + t + backup-at-type)) + (setq type-start backup-type-start + id-start backup-id-start) + (setq type-start start-pos + id-start start-pos)) + + ;; When these flags already are set we've found specifiers that + ;; unconditionally signal these attributes - backtracking doesn't + ;; change that. So keep them set in that case. + (or at-type-decl + (setq at-type-decl backup-at-type-decl)) + (or maybe-typeless + (setq maybe-typeless backup-maybe-typeless)) + + ,(unless short + ;; This identifier is bound only in the inner let. + '(setq start id-start)))) + +(defun c-forward-decl-or-cast-1 (preceding-token-end context last-cast-end) + ;; Move forward over a declaration or a cast if at the start of one. + ;; The point is assumed to be at the start of some token. Nil is + ;; returned if no declaration or cast is recognized, and the point + ;; is clobbered in that case. + ;; + ;; If a declaration is parsed: + ;; + ;; The point is left at the first token after the first complete + ;; declarator, if there is one. The return value is a cons where + ;; the car is the position of the first token in the declarator. + ;; Some examples: + ;; + ;; void foo (int a, char *b) stuff ... + ;; car ^ ^ point + ;; float (*a)[], b; + ;; car ^ ^ point + ;; unsigned int a = c_style_initializer, b; + ;; car ^ ^ point + ;; unsigned int a (cplusplus_style_initializer), b; + ;; car ^ ^ point (might change) + ;; class Foo : public Bar {} + ;; car ^ ^ point + ;; class PikeClass (int a, string b) stuff ... + ;; car ^ ^ point + ;; enum bool; + ;; car ^ ^ point + ;; enum bool flag; + ;; car ^ ^ point + ;; void cplusplus_function (int x) throw (Bad); + ;; car ^ ^ point + ;; Foo::Foo (int b) : Base (b) {} + ;; car ^ ^ point + ;; + ;; The cdr of the return value is non-nil iff a + ;; `c-typedef-decl-kwds' specifier is found in the declaration, + ;; i.e. the declared identifier(s) are types. + ;; + ;; If a cast is parsed: + ;; + ;; The point is left at the first token after the closing paren of + ;; the cast. The return value is `cast'. Note that the start + ;; position must be at the first token inside the cast parenthesis + ;; to recognize it. + ;; + ;; PRECEDING-TOKEN-END is the first position after the preceding + ;; token, i.e. on the other side of the syntactic ws from the point. + ;; Use a value less than or equal to (point-min) if the point is at + ;; the first token in (the visible part of) the buffer. + ;; + ;; CONTEXT is a symbol that describes the context at the point: + ;; 'decl In a comma-separatded declaration context (typically + ;; inside a function declaration arglist). + ;; '<> In an angle bracket arglist. + ;; 'arglist Some other type of arglist. + ;; nil Some other context or unknown context. + ;; + ;; LAST-CAST-END is the first token after the closing paren of a + ;; preceding cast, or nil if none is known. If + ;; `c-forward-decl-or-cast-1' is used in succession, it should be + ;; the position after the closest preceding call where a cast was + ;; matched. In that case it's used to discover chains of casts like + ;; "(a) (b) c". + ;; + ;; This function records identifier ranges on + ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if + ;; `c-record-type-identifiers' is non-nil. + ;; + ;; This function might do hidden buffer changes. + + (let (;; `start-pos' is used below to point to the start of the + ;; first type, i.e. after any leading specifiers. It might + ;; also point at the beginning of the preceding syntactic + ;; whitespace. + (start-pos (point)) + ;; Set to the result of `c-forward-type'. + at-type + ;; The position of the first token in what we currently + ;; believe is the type in the declaration or cast, after any + ;; specifiers and their associated clauses. + type-start + ;; The position of the first token in what we currently + ;; believe is the declarator for the first identifier. Set + ;; when the type is found, and moved forward over any + ;; `c-decl-hangon-kwds' and their associated clauses that + ;; occurs after the type. + id-start + ;; These store `at-type', `type-start' and `id-start' of the + ;; identifier before the one in those variables. The previous + ;; identifier might turn out to be the real type in a + ;; declaration if the last one has to be the declarator in it. + ;; If `backup-at-type' is nil then the other variables have + ;; undefined values. + backup-at-type backup-type-start backup-id-start + ;; Set if we've found a specifier that makes the defined + ;; identifier(s) types. + at-type-decl + ;; Set if we've found a specifier that can start a declaration + ;; where there's no type. + maybe-typeless + ;; If a specifier is found that also can be a type prefix, + ;; these flags are set instead of those above. If we need to + ;; back up an identifier, they are copied to the real flag + ;; variables. Thus they only take effect if we fail to + ;; interpret it as a type. + backup-at-type-decl backup-maybe-typeless + ;; Whether we've found a declaration or a cast. We might know + ;; this before we've found the type in it. It's 'ids if we've + ;; found two consecutive identifiers (usually a sure sign, but + ;; we should allow that in labels too), and t if we've found a + ;; specifier keyword (a 100% sure sign). + at-decl-or-cast + ;; Set when we need to back up to parse this as a declaration + ;; but not as a cast. + backup-if-not-cast + ;; For casts, the return position. + cast-end + ;; Save `c-record-type-identifiers' and + ;; `c-record-ref-identifiers' since ranges are recorded + ;; speculatively and should be thrown away if it turns out + ;; that it isn't a declaration or cast. + (save-rec-type-ids c-record-type-identifiers) + (save-rec-ref-ids c-record-ref-identifiers)) + + ;; Check for a type. Unknown symbols are treated as possible + ;; types, but they could also be specifiers disguised through + ;; macros like __INLINE__, so we recognize both types and known + ;; specifiers after them too. + (while + (let* ((start (point)) kwd-sym kwd-clause-end found-type) + + ;; Look for a specifier keyword clause. + (when (looking-at c-prefix-spec-kwds-re) + (setq kwd-sym (c-keyword-sym (match-string 1))) + (save-excursion + (c-forward-keyword-clause 1) + (setq kwd-clause-end (point)))) + + (when (setq found-type (c-forward-type)) + ;; Found a known or possible type or a prefix of a known type. + + (when at-type + ;; Got two identifiers with nothing but whitespace + ;; between them. That can only happen in declarations. + (setq at-decl-or-cast 'ids) + + (when (eq at-type 'found) + ;; If the previous identifier is a found type we + ;; record it as a real one; it might be some sort of + ;; alias for a prefix like "unsigned". + (save-excursion + (goto-char type-start) + (let ((c-promote-possible-types t)) + (c-forward-type))))) + + (setq backup-at-type at-type + backup-type-start type-start + backup-id-start id-start + at-type found-type + type-start start + id-start (point) + ;; The previous ambiguous specifier/type turned out + ;; to be a type since we've parsed another one after + ;; it, so clear these backup flags. + backup-at-type-decl nil + backup-maybe-typeless nil)) + + (if kwd-sym + (progn + ;; Handle known specifier keywords and + ;; `c-decl-hangon-kwds' which can occur after known + ;; types. + + (if (c-keyword-member kwd-sym 'c-decl-hangon-kwds) + ;; It's a hang-on keyword that can occur anywhere. + (progn + (setq at-decl-or-cast t) + (if at-type + ;; Move the identifier start position if + ;; we've passed a type. + (setq id-start kwd-clause-end) + ;; Otherwise treat this as a specifier and + ;; move the fallback position. + (setq start-pos kwd-clause-end)) + (goto-char kwd-clause-end)) + + ;; It's an ordinary specifier so we know that + ;; anything before this can't be the type. + (setq backup-at-type nil + start-pos kwd-clause-end) + + (if found-type + ;; It's ambiguous whether this keyword is a + ;; specifier or a type prefix, so set the backup + ;; flags. (It's assumed that `c-forward-type' + ;; moved further than `c-forward-keyword-clause'.) + (progn + (when (c-keyword-member kwd-sym 'c-typedef-decl-kwds) + (setq backup-at-type-decl t)) + (when (c-keyword-member kwd-sym 'c-typeless-decl-kwds) + (setq backup-maybe-typeless t))) + + (when (c-keyword-member kwd-sym 'c-typedef-decl-kwds) + (setq at-type-decl t)) + (when (c-keyword-member kwd-sym 'c-typeless-decl-kwds) + (setq maybe-typeless t)) + + ;; Haven't matched a type so it's an umambiguous + ;; specifier keyword and we know we're in a + ;; declaration. + (setq at-decl-or-cast t) + + (goto-char kwd-clause-end)))) + + ;; If the type isn't known we continue so that we'll jump + ;; over all specifiers and type identifiers. The reason + ;; to do this for a known type prefix is to make things + ;; like "unsigned INT16" work. + (and found-type (not (eq found-type t)))))) + + (cond + ((eq at-type t) + ;; If a known type was found, we still need to skip over any + ;; hangon keyword clauses after it. Otherwise it has already + ;; been done in the loop above. + (while (looking-at c-decl-hangon-key) + (c-forward-keyword-clause 1)) + (setq id-start (point))) + + ((eq at-type 'prefix) + ;; A prefix type is itself a primitive type when it's not + ;; followed by another type. + (setq at-type t)) + + ((not at-type) + ;; Got no type but set things up to continue anyway to handle + ;; the various cases when a declaration doesn't start with a + ;; type. + (setq id-start start-pos)) + + ((and (eq at-type 'maybe) + (c-major-mode-is 'c++-mode)) + ;; If it's C++ then check if the last "type" ends on the form + ;; "foo::foo" or "foo::~foo", i.e. if it's the name of a + ;; (con|de)structor. + (save-excursion + (let (name end-2 end-1) + (goto-char id-start) + (c-backward-syntactic-ws) + (setq end-2 (point)) + (when (and + (c-simple-skip-symbol-backward) + (progn + (setq name + (buffer-substring-no-properties (point) end-2)) + ;; Cheating in the handling of syntactic ws below. + (< (skip-chars-backward ":~ \t\n\r\v\f") 0)) + (progn + (setq end-1 (point)) + (c-simple-skip-symbol-backward)) + (>= (point) type-start) + (equal (buffer-substring-no-properties (point) end-1) + name)) + ;; It is a (con|de)structor name. In that case the + ;; declaration is typeless so zap out any preceding + ;; identifier(s) that we might have taken as types. + (goto-char type-start) + (setq at-type nil + backup-at-type nil + id-start type-start)))))) + + ;; Check for and step over a type decl expression after the thing + ;; that is or might be a type. This can't be skipped since we + ;; need the correct end position of the declarator for + ;; `max-type-decl-end-*'. + (let ((start (point)) (paren-depth 0) pos + ;; True if there's a non-open-paren match of + ;; `c-type-decl-prefix-key'. + got-prefix + ;; True if the declarator is surrounded by a parenthesis pair. + got-parens + ;; True if there is an identifier in the declarator. + got-identifier + ;; True if there's a non-close-paren match of + ;; `c-type-decl-suffix-key'. + got-suffix + ;; True if there's a prefix match outside the outermost + ;; paren pair that surrounds the declarator. + got-prefix-before-parens +y ;; True if there's a suffix match outside the outermost + ;; paren pair that surrounds the declarator. The value is + ;; the position of the first suffix match. + got-suffix-after-parens + ;; True if we've parsed the type decl to a token that is + ;; known to end declarations in this context. + at-decl-end + ;; The earlier values of `at-type' and `type-start' if we've + ;; shifted the type backwards. + identifier-type identifier-start + ;; If `c-parse-and-markup-<>-arglists' is set we need to + ;; turn it off during the name skipping below to avoid + ;; getting `c-type' properties that might be bogus. That + ;; can happen since we don't know if + ;; `c-restricted-<>-arglists' will be correct inside the + ;; arglist paren that gets entered. + c-parse-and-markup-<>-arglists) + + (goto-char id-start) + + ;; Skip over type decl prefix operators. (Note similar code in + ;; `c-font-lock-declarators'.) + (while (and (looking-at c-type-decl-prefix-key) + (if (and (c-major-mode-is 'c++-mode) + (match-beginning 2)) + ;; If the second submatch matches in C++ then + ;; we're looking at an identifier that's a + ;; prefix only if it specifies a member pointer. + (when (setq got-identifier (c-forward-name)) + (if (looking-at "\\(::\\)") + ;; We only check for a trailing "::" and + ;; let the "*" that should follow be + ;; matched in the next round. + (progn (setq got-identifier nil) t) + ;; It turned out to be the real identifier, + ;; so stop. + nil)) + t)) + + (if (eq (char-after) ?\() + (progn + (setq paren-depth (1+ paren-depth)) + (forward-char)) + (unless got-prefix-before-parens + (setq got-prefix-before-parens (= paren-depth 0))) + (setq got-prefix t) + (goto-char (match-end 1))) + (c-forward-syntactic-ws)) + + (setq got-parens (> paren-depth 0)) + + ;; Skip over an identifier. + (or got-identifier + (and (looking-at c-identifier-start) + (setq got-identifier (c-forward-name)))) + + ;; Skip over type decl suffix operators. + (while (if (looking-at c-type-decl-suffix-key) + + (if (eq (char-after) ?\)) + (when (> paren-depth 0) + (setq paren-depth (1- paren-depth)) + (forward-char) + t) + (when (if (save-match-data (looking-at "\\s\(")) + (c-safe (c-forward-sexp 1) t) + (goto-char (match-end 1)) + t) + (when (and (not got-suffix-after-parens) + (= paren-depth 0)) + (setq got-suffix-after-parens (match-beginning 0))) + (setq got-suffix t))) + + ;; No suffix matched. We might have matched the + ;; identifier as a type and the open paren of a + ;; function arglist as a type decl prefix. In that + ;; case we should "backtrack": Reinterpret the last + ;; type as the identifier, move out of the arglist and + ;; continue searching for suffix operators. + ;; + ;; Do this even if there's no preceding type, to cope + ;; with old style function declarations in K&R C, + ;; (con|de)structors in C++ and `c-typeless-decl-kwds' + ;; style declarations. That isn't applicable in an + ;; arglist context, though. + (when (and (= paren-depth 1) + (not got-prefix-before-parens) + (not (eq at-type t)) + (or backup-at-type + maybe-typeless + backup-maybe-typeless + (when c-recognize-typeless-decls + (not context))) + (setq pos (c-up-list-forward (point))) + (eq (char-before pos) ?\))) + (c-fdoc-shift-type-backward) + (goto-char pos) + t)) + + (c-forward-syntactic-ws)) + + (when (and (or maybe-typeless backup-maybe-typeless) + (not got-identifier) + (not got-prefix) + at-type) + ;; Have found no identifier but `c-typeless-decl-kwds' has + ;; matched so we know we're inside a declaration. The + ;; preceding type must be the identifier instead. + (c-fdoc-shift-type-backward)) + + (setq + at-decl-or-cast + (catch 'at-decl-or-cast + + (when (> paren-depth 0) + ;; Encountered something inside parens that isn't matched by + ;; the `c-type-decl-*' regexps, so it's not a type decl + ;; expression. Try to skip out to the same paren depth to + ;; not confuse the cast check below. + (c-safe (goto-char (scan-lists (point) 1 paren-depth))) + ;; If we've found a specifier keyword then it's a + ;; declaration regardless. + (throw 'at-decl-or-cast (eq at-decl-or-cast t))) + + (setq at-decl-end + (looking-at (cond ((eq context '<>) "[,>]") + (context "[,\)]") + (t "[,;]")))) + + ;; Now we've collected info about various characteristics of + ;; the construct we're looking at. Below follows a decision + ;; tree based on that. It's ordered to check more certain + ;; signs before less certain ones. + + (if got-identifier + (progn + + (when (and (or at-type maybe-typeless) + (not (or got-prefix got-parens))) + ;; Got another identifier directly after the type, so it's a + ;; declaration. + (throw 'at-decl-or-cast t)) + + (when (and got-parens + (not got-prefix) + (not got-suffix-after-parens) + (or backup-at-type + maybe-typeless + backup-maybe-typeless)) + ;; Got a declaration of the form "foo bar (gnu);" where we've + ;; recognized "bar" as the type and "gnu" as the declarator. + ;; In this case it's however more likely that "bar" is the + ;; declarator and "gnu" a function argument or initializer (if + ;; `c-recognize-paren-inits' is set), since the parens around + ;; "gnu" would be superfluous if it's a declarator. Shift the + ;; type one step backward. + (c-fdoc-shift-type-backward))) + + ;; Found no identifier. + + (if backup-at-type + (progn + + (when (= (point) start) + ;; Got a plain list of identifiers. If a colon follows it's + ;; a valid label. Otherwise the last one probably is the + ;; declared identifier and we should back up to the previous + ;; type, providing it isn't a cast. + (if (eq (char-after) ?:) + ;; If we've found a specifier keyword then it's a + ;; declaration regardless. + (throw 'at-decl-or-cast (eq at-decl-or-cast t)) + (setq backup-if-not-cast t) + (throw 'at-decl-or-cast t))) + + (when (and got-suffix + (not got-prefix) + (not got-parens)) + ;; Got a plain list of identifiers followed by some suffix. + ;; If this isn't a cast then the last identifier probably is + ;; the declared one and we should back up to the previous + ;; type. + (setq backup-if-not-cast t) + (throw 'at-decl-or-cast t))) + + (when (eq at-type t) + ;; If the type is known we know that there can't be any + ;; identifier somewhere else, and it's only in declarations in + ;; e.g. function prototypes and in casts that the identifier may + ;; be left out. + (throw 'at-decl-or-cast t)) + + (when (= (point) start) + ;; Only got a single identifier (parsed as a type so far). + (if (and + ;; Check that the identifier isn't at the start of an + ;; expression. + at-decl-end + (cond + ((eq context 'decl) + ;; Inside an arglist that contains declarations. If K&R + ;; style declarations and parenthesis style initializers + ;; aren't allowed then the single identifier must be a + ;; type, else we require that it's known or found + ;; (primitive types are handled above). + (or (and (not c-recognize-knr-p) + (not c-recognize-paren-inits)) + (memq at-type '(known found)))) + ((eq context '<>) + ;; Inside a template arglist. Accept known and found + ;; types; other identifiers could just as well be + ;; constants in C++. + (memq at-type '(known found))))) + (throw 'at-decl-or-cast t) + ;; Can't be a valid declaration or cast, but if we've found a + ;; specifier it can't be anything else either, so treat it as + ;; an invalid/unfinished declaration or cast. + (throw 'at-decl-or-cast at-decl-or-cast)))) + + (if (and got-parens + (not got-prefix) + (not context) + (not (eq at-type t)) + (or backup-at-type + maybe-typeless + backup-maybe-typeless + (when c-recognize-typeless-decls + (or (not got-suffix) + (not (looking-at + c-after-suffixed-type-maybe-decl-key)))))) + ;; Got an empty paren pair and a preceding type that probably + ;; really is the identifier. Shift the type backwards to make + ;; the last one the identifier. This is analogous to the + ;; "backtracking" done inside the `c-type-decl-suffix-key' loop + ;; above. + ;; + ;; Exception: In addition to the conditions in that + ;; "backtracking" code, do not shift backward if we're not + ;; looking at either `c-after-suffixed-type-decl-key' or "[;,]". + ;; Since there's no preceding type, the shift would mean that + ;; the declaration is typeless. But if the regexp doesn't match + ;; then we will simply fall through in the tests below and not + ;; recognize it at all, so it's better to try it as an abstract + ;; declarator instead. + (c-fdoc-shift-type-backward) + + ;; Still no identifier. + + (when (and got-prefix (or got-parens got-suffix)) + ;; Require `got-prefix' together with either `got-parens' or + ;; `got-suffix' to recognize it as an abstract declarator: + ;; `got-parens' only is probably an empty function call. + ;; `got-suffix' only can build an ordinary expression together + ;; with the preceding identifier which we've taken as a type. + ;; We could actually accept on `got-prefix' only, but that can + ;; easily occur temporarily while writing an expression so we + ;; avoid that case anyway. We could do a better job if we knew + ;; the point when the fontification was invoked. + (throw 'at-decl-or-cast t)) + + (when (and at-type + (not got-prefix) + (not got-parens) + got-suffix-after-parens + (eq (char-after got-suffix-after-parens) ?\()) + ;; Got a type, no declarator but a paren suffix. I.e. it's a + ;; normal function call afterall (or perhaps a C++ style object + ;; instantiation expression). + (throw 'at-decl-or-cast nil)))) + + (when at-decl-or-cast + ;; By now we've located the type in the declaration that we know + ;; we're in. + (throw 'at-decl-or-cast t)) + + (when (and got-identifier + (not context) + (looking-at c-after-suffixed-type-decl-key) + (if (and got-parens + (not got-prefix) + (not got-suffix) + (not (eq at-type t))) + ;; Shift the type backward in the case that there's a + ;; single identifier inside parens. That can only + ;; occur in K&R style function declarations so it's + ;; more likely that it really is a function call. + ;; Therefore we only do this after + ;; `c-after-suffixed-type-decl-key' has matched. + (progn (c-fdoc-shift-type-backward) t) + got-suffix-after-parens)) + ;; A declaration according to `c-after-suffixed-type-decl-key'. + (throw 'at-decl-or-cast t)) + + (when (and (or got-prefix (not got-parens)) + (memq at-type '(t known))) + ;; It's a declaration if a known type precedes it and it can't be a + ;; function call. + (throw 'at-decl-or-cast t)) + + ;; If we get here we can't tell if this is a type decl or a normal + ;; expression by looking at it alone. (That's under the assumption + ;; that normal expressions always can look like type decl expressions, + ;; which isn't really true but the cases where it doesn't hold are so + ;; uncommon (e.g. some placements of "const" in C++) it's not worth + ;; the effort to look for them.) + + (unless (or at-decl-end (looking-at "=[^=]")) + ;; If this is a declaration it should end here or its initializer(*) + ;; should start here, so check for allowed separation tokens. Note + ;; that this rule doesn't work e.g. with a K&R arglist after a + ;; function header. + ;; + ;; *) Don't check for C++ style initializers using parens + ;; since those already have been matched as suffixes. + ;; + ;; If `at-decl-or-cast' is then we've found some other sign that + ;; it's a declaration or cast, so then it's probably an + ;; invalid/unfinished one. + (throw 'at-decl-or-cast at-decl-or-cast)) + + ;; Below are tests that only should be applied when we're certain to + ;; not have parsed halfway through an expression. + + (when (memq at-type '(t known)) + ;; The expression starts with a known type so treat it as a + ;; declaration. + (throw 'at-decl-or-cast t)) + + (when (and (c-major-mode-is 'c++-mode) + ;; In C++ we check if the identifier is a known type, since + ;; (con|de)structors use the class name as identifier. + ;; We've always shifted over the identifier as a type and + ;; then backed up again in this case. + identifier-type + (or (memq identifier-type '(found known)) + (and (eq (char-after identifier-start) ?~) + ;; `at-type' probably won't be 'found for + ;; destructors since the "~" is then part of the + ;; type name being checked against the list of + ;; known types, so do a check without that + ;; operator. + (or (save-excursion + (goto-char (1+ identifier-start)) + (c-forward-syntactic-ws) + (c-with-syntax-table + c-identifier-syntax-table + (looking-at c-known-type-key))) + (save-excursion + (goto-char (1+ identifier-start)) + ;; We have already parsed the type earlier, + ;; so it'd be possible to cache the end + ;; position instead of redoing it here, but + ;; then we'd need to keep track of another + ;; position everywhere. + (c-check-type (point) + (progn (c-forward-type) + (point)))))))) + (throw 'at-decl-or-cast t)) + + (if got-identifier + (progn + (when (and got-prefix-before-parens + at-type + (or at-decl-end (looking-at "=[^=]")) + (not context) + (not got-suffix)) + ;; Got something like "foo * bar;". Since we're not inside an + ;; arglist it would be a meaningless expression because the + ;; result isn't used. We therefore choose to recognize it as + ;; a declaration. Do not allow a suffix since it could then + ;; be a function call. + (throw 'at-decl-or-cast t)) + + (when (and (or got-suffix-after-parens + (looking-at "=[^=]")) + (eq at-type 'found) + (not (eq context 'arglist))) + ;; Got something like "a (*b) (c);" or "a (b) = c;". It could + ;; be an odd expression or it could be a declaration. Treat + ;; it as a declaration if "a" has been used as a type + ;; somewhere else (if it's a known type we won't get here). + (throw 'at-decl-or-cast t))) + + (when (and context + (or got-prefix + (and (eq context 'decl) + (not c-recognize-paren-inits) + (or got-parens got-suffix)))) + ;; Got a type followed by an abstract declarator. If `got-prefix' + ;; is set it's something like "a *" without anything after it. If + ;; `got-parens' or `got-suffix' is set it's "a()", "a[]", "a()[]", + ;; or similar, which we accept only if the context rules out + ;; expressions. + (throw 'at-decl-or-cast t))) + + ;; If we had a complete symbol table here (which rules out + ;; `c-found-types') we should return t due to the disambiguation rule + ;; (in at least C++) that anything that can be parsed as a declaration + ;; is a declaration. Now we're being more defensive and prefer to + ;; highlight things like "foo (bar);" as a declaration only if we're + ;; inside an arglist that contains declarations. + (eq context 'decl)))) + + ;; The point is now after the type decl expression. + + (cond + ;; Check for a cast. + ((save-excursion + (and + c-cast-parens + + ;; Should be the first type/identifier in a cast paren. + (> preceding-token-end (point-min)) + (memq (char-before preceding-token-end) c-cast-parens) + + ;; The closing paren should follow. + (progn + (c-forward-syntactic-ws) + (looking-at "\\s\)")) + + ;; There should be a primary expression after it. + (let (pos) + (forward-char) + (c-forward-syntactic-ws) + (setq cast-end (point)) + (and (looking-at c-primary-expr-regexp) + (progn + (setq pos (match-end 0)) + (or + ;; Check if the expression begins with a prefix keyword. + (match-beginning 2) + (if (match-beginning 1) + ;; Expression begins with an ambiguous operator. Treat + ;; it as a cast if it's a type decl or if we've + ;; recognized the type somewhere else. + (or at-decl-or-cast + (memq at-type '(t known found))) + ;; Unless it's a keyword, it's the beginning of a primary + ;; expression. + (not (looking-at c-keywords-regexp))))) + ;; If `c-primary-expr-regexp' matched a nonsymbol token, check + ;; that it matched a whole one so that we don't e.g. confuse + ;; the operator '-' with '->'. It's ok if it matches further, + ;; though, since it e.g. can match the float '.5' while the + ;; operator regexp only matches '.'. + (or (not (looking-at c-nonsymbol-token-regexp)) + (<= (match-end 0) pos)))) + + ;; There should either be a cast before it or something that isn't an + ;; identifier or close paren. + (> preceding-token-end (point-min)) + (progn + (goto-char (1- preceding-token-end)) + (or (eq (point) last-cast-end) + (progn + (c-backward-syntactic-ws) + (if (< (skip-syntax-backward "w_") 0) + ;; It's a symbol. Accept it only if it's one of the + ;; keywords that can precede an expression (without + ;; surrounding parens). + (looking-at c-simple-stmt-key) + (and + ;; Check that it isn't a close paren (block close is ok, + ;; though). + (not (memq (char-before) '(?\) ?\]))) + ;; Check that it isn't a nonsymbol identifier. + (not (c-on-identifier))))))))) + + ;; Handle the cast. + (when (and c-record-type-identifiers at-type (not (eq at-type t))) + (let ((c-promote-possible-types t)) + (goto-char type-start) + (c-forward-type))) + + (goto-char cast-end) + 'cast) + + (at-decl-or-cast + ;; We're at a declaration. Highlight the type and the following + ;; declarators. + + (when backup-if-not-cast + (c-fdoc-shift-type-backward t)) + + (when (and (eq context 'decl) (looking-at ",")) + ;; Make sure to propagate the `c-decl-arg-start' property to + ;; the next argument if it's set in this one, to cope with + ;; interactive refontification. + (c-put-c-type-property (point) 'c-decl-arg-start)) + + (when (and c-record-type-identifiers at-type (not (eq at-type t))) + (let ((c-promote-possible-types t)) + (save-excursion + (goto-char type-start) + (c-forward-type)))) + + (cons id-start at-type-decl)) + + (t + ;; False alarm. Restore the recorded ranges. + (setq c-record-type-identifiers save-rec-type-ids + c-record-ref-identifiers save-rec-ref-ids) + nil)))) + +(defun c-forward-label (&optional assume-markup preceding-token-end limit) + ;; Assuming the point is at the beginning of a token, check if it + ;; starts a label and if so move over it and return t, otherwise + ;; don't move and return nil. The end of the label is taken to be + ;; the end of the first submatch in `c-opt-extra-label-key' if it + ;; matched, otherwise it's the colon. The point is directly after + ;; the end on return. The terminating char is marked with + ;; `c-decl-end' to improve recognition of the following declaration + ;; or statement. + ;; + ;; If ASSUME-MARKUP is non-nil, it's assumed that the preceding + ;; label, if any, has been marked up like that. + ;; + ;; If PRECEDING-TOKEN-END is given, it should be the first position + ;; after the preceding token, i.e. on the other side of the + ;; syntactic ws from the point. Use a value less than or equal to + ;; (point-min) if the point is at the first token in (the visible + ;; part of) the buffer. + ;; + ;; The optional LIMIT limits the forward scan for the colon. + ;; + ;; This function records the ranges of the label symbols on + ;; `c-record-ref-identifiers' if `c-record-type-identifiers' (!) is + ;; non-nil. + ;; + ;; This function might do hidden buffer changes. + + (let ((start (point))) + (cond + ((looking-at c-label-kwds-regexp) + (let ((kwd-end (match-end 1))) + ;; Record only the keyword itself for fontification, since in + ;; case labels the following is a constant expression and not + ;; a label. + (when c-record-type-identifiers + (c-record-ref-id (cons (match-beginning 1) kwd-end))) + + ;; Find the label end. + (goto-char kwd-end) + (if (and (c-syntactic-re-search-forward + ;; Stop on chars that aren't allowed in expressions, + ;; and on operator chars that would be meaningless + ;; there. FIXME: This doesn't cope with ?: operators. + "[;{=,@]\\|\\(\\=\\|[^:]\\):\\([^:]\\|\\'\\)" + limit t t nil 1) + (match-beginning 2)) + + (progn + (goto-char (match-beginning 2)) + (c-put-c-type-property (1- (point)) 'c-decl-end) + t) + + ;; It's an unfinished label. We consider the keyword enough + ;; to recognize it as a label, so that it gets fontified. + ;; Leave the point at the end of it, but don't put any + ;; `c-decl-end' marker. + (goto-char kwd-end) + t))) + + ((and c-opt-extra-label-key + (looking-at c-opt-extra-label-key)) + ;; For a `c-opt-extra-label-key' match, we record the whole + ;; thing for fontification. That's to get the leading '@' in + ;; Objective-C protection labels fontified. + (goto-char (match-end 1)) + (when c-record-type-identifiers + (c-record-ref-id (cons (match-beginning 1) (point)))) + (c-put-c-type-property (1- (point)) 'c-decl-end) + t) + + ((and c-recognize-colon-labels + + ;; A colon label must have something before the colon. + (not (eq (char-after) ?:)) + + ;; Check that we're not after a token that can't precede a label. + (or + ;; Trivially succeeds when there's no preceding token. + (if preceding-token-end + (<= preceding-token-end (point-min)) + (save-excursion + (c-backward-syntactic-ws) + (setq preceding-token-end (point)) + (bobp))) + + ;; Check if we're after a label, if we're after a closing + ;; paren that belong to statement, and with + ;; `c-label-prefix-re'. It's done in different order + ;; depending on `assume-markup' since the checks have + ;; different expensiveness. + (if assume-markup + (or + (eq (c-get-char-property (1- preceding-token-end) 'c-type) + 'c-decl-end) + + (save-excursion + (goto-char (1- preceding-token-end)) + (c-beginning-of-current-token) + (looking-at c-label-prefix-re)) + + (and (eq (char-before preceding-token-end) ?\)) + (c-after-conditional))) + + (or + (save-excursion + (goto-char (1- preceding-token-end)) + (c-beginning-of-current-token) + (looking-at c-label-prefix-re)) + + (cond + ((eq (char-before preceding-token-end) ?\)) + (c-after-conditional)) + + ((eq (char-before preceding-token-end) ?:) + ;; Might be after another label, so check it recursively. + (save-excursion + (goto-char (1- preceding-token-end)) + ;; Essentially the same as the + ;; `c-syntactic-re-search-forward' regexp below. + (c-syntactic-skip-backward "^-]:?;}=*/%&|,<>!@+" nil t) + (let ((pte (point)) + ;; If the caller turned on recording for us, + ;; it shouldn't apply when we check the + ;; preceding label. + c-record-type-identifiers) + (c-forward-syntactic-ws) + (c-forward-label nil pte start)))))))) + + ;; Check that the next nonsymbol token is ":". Allow '(' + ;; for the sake of macro arguments. FIXME: Should build + ;; this regexp from the language constants. + (c-syntactic-re-search-forward + "[[:?;{=*/%&|,<>!@+-]" limit t t) + (eq (char-before) ?:) + (not (eq (char-after) ?:))) + + (save-restriction + (narrow-to-region start (point)) + + ;; Check that `c-nonlabel-token-key' doesn't match anywhere. + (catch 'check-label + (goto-char start) + (while (progn + (when (looking-at c-nonlabel-token-key) + (goto-char start) + (throw 'check-label nil)) + (and (c-safe (c-forward-sexp) + (c-forward-syntactic-ws) + t) + (not (eobp))))) + + ;; Record the identifiers in the label for fontification, unless + ;; it begins with `c-label-kwds' in which case the following + ;; identifiers are part of a (constant) expression that + ;; shouldn't be fontified. + (when (and c-record-type-identifiers + (progn (goto-char start) + (not (looking-at c-label-kwds-regexp)))) + (while (c-syntactic-re-search-forward c-symbol-key nil t) + (c-record-ref-id (cons (match-beginning 0) + (match-end 0))))) + + (c-put-c-type-property (1- (point-max)) 'c-decl-end) + (goto-char (point-max)) + t))) + + (t + ;; Not a label. + (goto-char start) + nil)))) + +(defun c-forward-objc-directive () + ;; Assuming the point is at the beginning of a token, try to move + ;; forward to the end of the Objective-C directive that starts + ;; there. Return t if a directive was fully recognized, otherwise + ;; the point is moved as far as one could be successfully parsed and + ;; nil is returned. + ;; + ;; This function records identifier ranges on + ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if + ;; `c-record-type-identifiers' is non-nil. + ;; + ;; This function might do hidden buffer changes. + + (let ((start (point)) + start-char + (c-promote-possible-types t) + ;; Turn off recognition of angle bracket arglists while parsing + ;; types here since the protocol reference list might then be + ;; considered part of the preceding name or superclass-name. + c-recognize-<>-arglists) + + (if (or + (when (looking-at + (eval-when-compile + (c-make-keywords-re t + (append (c-lang-const c-protection-kwds objc) + '("@end")) + 'objc-mode))) + (goto-char (match-end 1)) + t) + + (and + (looking-at + (eval-when-compile + (c-make-keywords-re t + '("@interface" "@implementation" "@protocol") + 'objc-mode))) + + ;; Handle the name of the class itself. + (progn + (c-forward-token-2) + (c-forward-type)) + + (catch 'break + ;; Look for ": superclass-name" or "( category-name )". + (when (looking-at "[:\(]") + (setq start-char (char-after)) + (forward-char) + (c-forward-syntactic-ws) + (unless (c-forward-type) (throw 'break nil)) + (when (eq start-char ?\() + (unless (eq (char-after) ?\)) (throw 'break nil)) + (forward-char) + (c-forward-syntactic-ws))) + + ;; Look for a protocol reference list. + (if (eq (char-after) ?<) + (let ((c-recognize-<>-arglists t) + (c-parse-and-markup-<>-arglists t) + c-restricted-<>-arglists) + (c-forward-<>-arglist t)) + t)))) + + (progn + (c-backward-syntactic-ws) + (c-clear-c-type-property start (1- (point)) 'c-decl-end) + (c-put-c-type-property (1- (point)) 'c-decl-end) + t) + + (c-clear-c-type-property start (point) 'c-decl-end) + nil))) + (defun c-beginning-of-inheritance-list (&optional lim) ;; Go to the first non-whitespace after the colon that starts a ;; multiple inheritance introduction. Optional LIM is the farthest ;; back we should search. - (let* ((lim (or lim (save-excursion - (c-beginning-of-syntax) - (point))))) - (c-with-syntax-table c++-template-syntax-table - (c-backward-token-2 0 t lim) - (while (and (or (looking-at c-symbol-start) - (looking-at "[<,]\\|::")) - (zerop (c-backward-token-2 1 t lim)))) - (skip-chars-forward "^:")))) + ;; + ;; This function might do hidden buffer changes. + (c-with-syntax-table c++-template-syntax-table + (c-backward-token-2 0 t lim) + (while (and (or (looking-at c-symbol-start) + (looking-at "[<,]\\|::")) + (zerop (c-backward-token-2 1 t lim)))))) (defun c-in-method-def-p () ;; Return nil if we aren't in a method definition, otherwise the ;; position of the initial [+-]. + ;; + ;; This function might do hidden buffer changes. (save-excursion (beginning-of-line) (and c-opt-method-key @@ -4327,6 +6055,8 @@ ;; Only one level of enclosing parentheses is considered, so for ;; instance `nil' is returned when in a function call within an asm ;; operand. + ;; + ;; This function might do hidden buffer changes. (and c-opt-asm-stmt-key (save-excursion @@ -4347,79 +6077,65 @@ Otherwise, a 2-vector is returned where the zeroth element is the buffer position of the start of the class declaration, and the first element is the buffer position of the enclosing class's opening -brace." +brace. + +Note that this function might do hidden buffer changes. See the +comment at the start of cc-engine.el for more info." (let ((paren-state (c-parse-state))) (or (not (c-most-enclosing-brace paren-state)) (c-search-uplist-for-classkey paren-state)))) (defun c-just-after-func-arglist-p (&optional lim) - ;; Return non-nil if we are between a function's argument list closing - ;; paren and its opening brace. Note that the list close brace - ;; could be followed by a "const" specifier or a member init hanging - ;; colon. LIM is used as bound for some backward buffer searches; - ;; the search might continue past it. - ;; - ;; Note: This test is easily fooled. It only works reasonably well - ;; in the situations where `c-guess-basic-syntax' uses it. - (save-excursion - (if (c-mode-is-new-awk-p) - (c-awk-backward-syntactic-ws lim) - (c-backward-syntactic-ws lim)) - (let ((checkpoint (point))) - ;; could be looking at const specifier - (if (and (eq (char-before) ?t) - (forward-word -1) - (looking-at "\\[^_]")) - (c-backward-syntactic-ws lim) - ;; otherwise, we could be looking at a hanging member init - ;; colon - (goto-char checkpoint) - (while (and - (eq (char-before) ?,) - ;; this will catch member inits with multiple - ;; line arglists - (progn - (forward-char -1) - (c-backward-syntactic-ws (c-point 'bol)) - (c-safe (c-backward-sexp 1) t)) - (or (not (looking-at "\\s\(")) - (c-safe (c-backward-sexp 1) t))) - (c-backward-syntactic-ws lim)) - (if (and (eq (char-before) ?:) - (progn - (forward-char -1) - (c-backward-syntactic-ws lim) - (looking-at "\\([ \t\n]\\|\\\\\n\\)*:\\([^:]+\\|$\\)"))) - nil - (goto-char checkpoint)) - ) - (setq checkpoint (point)) - (and (eq (char-before) ?\)) - ;; Check that it isn't a cpp expression, e.g. the - ;; expression of an #if directive or the "function header" - ;; of a #define. - (or (not (c-beginning-of-macro)) - (and (c-forward-to-cpp-define-body) - (< (point) checkpoint))) - ;; Check if we are looking at an ObjC method def or a class - ;; category. - (not (and c-opt-method-key - (progn - (goto-char checkpoint) - (c-safe (c-backward-sexp) t)) - (progn - (c-backward-syntactic-ws lim) - (or (memq (char-before) '(?- ?+)) - (and (c-safe (c-forward-sexp -2) t) - (looking-at c-class-key)))))) - ;; Pike has compound types that include parens, - ;; e.g. "array(string)". Check that we aren't after one. - (not (and (c-major-mode-is 'pike-mode) - (progn - (goto-char checkpoint) - (c-safe (c-backward-sexp 2) t)) - (looking-at c-primitive-type-key))) - )))) + ;; Return non-nil if the point is in the region after the argument + ;; list of a function and its opening brace (or semicolon in case it + ;; got no body). If there are K&R style argument declarations in + ;; that region, the point has to be inside the first one for this + ;; function to recognize it. + ;; + ;; If successful, the point is moved to the first token after the + ;; function header (see `c-forward-decl-or-cast-1' for details) and + ;; the position of the opening paren of the function arglist is + ;; returned. + ;; + ;; The point is clobbered if not successful. + ;; + ;; LIM is used as bound for backward buffer searches. + ;; + ;; This function might do hidden buffer changes. + + (let ((beg (point)) end id-start) + (and + (eq (c-beginning-of-statement-1 lim) 'same) + + (not (or (c-major-mode-is 'objc-mode) + (c-forward-objc-directive))) + + (setq id-start + (car-safe (c-forward-decl-or-cast-1 (c-point 'bosws) nil nil))) + (< id-start beg) + + ;; There should not be a '=' or ',' between beg and the + ;; start of the declaration since that means we were in the + ;; "expression part" of the declaration. + (or (> (point) beg) + (not (looking-at "[=,]"))) + + (save-excursion + ;; Check that there's an arglist paren in the + ;; declaration. + (goto-char id-start) + (cond ((eq (char-after) ?\() + ;; The declarator is a paren expression, so skip past it + ;; so that we don't get stuck on that instead of the + ;; function arglist. + (c-forward-sexp)) + ((and c-opt-op-identitier-prefix + (looking-at c-opt-op-identitier-prefix)) + ;; Don't trip up on "operator ()". + (c-forward-token-2 2 t))) + (and (< (point) beg) + (c-syntactic-re-search-forward "(" beg t t) + (1- (point))))))) (defun c-in-knr-argdecl (&optional lim) ;; Return the position of the first argument declaration if point is @@ -4429,6 +6145,8 @@ ;; ;; Note: A declaration level context is assumed; the test can return ;; false positives for statements. + ;; + ;; This function might do hidden buffer changes. (save-excursion (save-restriction @@ -4488,6 +6206,8 @@ (defun c-skip-conditional () ;; skip forward over conditional at point, including any predicate ;; statements in parentheses. No error checking is performed. + ;; + ;; This function might do hidden buffer changes. (c-forward-sexp (cond ;; else if() ((looking-at (concat "\\