diff options
35 files changed, 830 insertions, 654 deletions
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index ca8abe54ace..65a97a46699 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -2038,32 +2038,35 @@ forward slash (@samp{/}) character. @node Directory Names @subsection Directory Names @cindex directory name +@cindex directory file name @cindex file name of directory A @dfn{directory name} is the name of a directory. A directory is -actually a kind of file, so it has a file name, which is related to -the directory name but not identical to it. (This is not quite the -same as the usual Unix terminology.) These two different names for -the same entity are related by a syntactic transformation. On GNU and -Unix systems, this is simple: a directory name ends in a slash, -whereas the directory's name as a file lacks that slash. On MS-DOS -the relationship is more complicated. - - The difference between a directory name and its name as a file is +actually a kind of file, so it has a file name (called the +@dfn{directory file name}, which is related to the directory name but +not identical to it. (This is not quite the same as the usual Unix +terminology.) These two different names for the same entity are +related by a syntactic transformation. On GNU and Unix systems, this +is simple: a directory name ends in a slash, whereas the directory +file name lacks that slash. On MS-DOS the relationship is more +complicated. + + The difference between directory name and directory file name is subtle but crucial. When an Emacs variable or function argument is -described as being a directory name, a file name of a directory is not +described as being a directory name, a directory file name is not acceptable. When @code{file-name-directory} returns a string, that is always a directory name. - The following two functions convert between directory names and file -names. They do nothing special with environment variable substitutions -such as @samp{$HOME}, and the constructs @samp{~}, @samp{.} and @samp{..}. + The following two functions convert between directory names and +directory file names. They do nothing special with environment +variable substitutions such as @samp{$HOME}, and the constructs +@samp{~}, @samp{.} and @samp{..}. @defun file-name-as-directory filename This function returns a string representing @var{filename} in a form -that the operating system will interpret as the name of a directory. On -most systems, this means appending a slash to the string (if it does not -already end in one). +that the operating system will interpret as the name of a directory (a +directory name). On most systems, this means appending a slash to the +string (if it does not already end in one). @example @group @@ -2074,10 +2077,10 @@ already end in one). @end defun @defun directory-file-name dirname -This function returns a string representing @var{dirname} in a form that -the operating system will interpret as the name of a file. On most -systems, this means removing the final slash (or backslash) from the -string. +This function returns a string representing @var{dirname} in a form +that the operating system will interpret as the name of a file (a +directory file name). On most systems, this means removing the final +slash (or backslash) from the string. @example @group @@ -2119,6 +2122,13 @@ Don't try concatenating a slash by hand, as in because this is not portable. Always use @code{file-name-as-directory}. + To avoid the issues mentioned above, or if the @var{dirname} value +might be nil (for example, from an element of @code{load-path}), use: + +@example +(expand-file-name @var{relfile} @var{dirname}) +@end example + To convert a directory name to its abbreviation, use this function: diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 0160de82086..7050df86a18 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -2697,6 +2697,11 @@ watch library. Otherwise, the actions @code{deleted} and (rename-file "/tmp/foo" "/tmp/bla") @result{} Event (35025468 renamed "/tmp/foo" "/tmp/bla") @end group + +@group +(delete-file "/tmp/bla") + @result{} Event (35025468 deleted "/tmp/bla") +@end group @end example @end defun @@ -2718,15 +2723,15 @@ also makes it invalid. @example @group -(setq desc (file-notify-add-watch - "/tmp/foo" '(change) 'my-notify-callback)) - @result{} 35025468 +(make-directory "/tmp/foo") + @result{} nil @end group @group -(write-region "foo" nil "/tmp/foo") - @result{} Event (35025468 created "/tmp/foo") - Event (35025468 changed "/tmp/foo") +(setq desc + (file-notify-add-watch + "/tmp/foo" '(change) 'my-notify-callback)) + @result{} 35025468 @end group @group @@ -2735,8 +2740,32 @@ also makes it invalid. @end group @group -(delete-file "/tmp/foo") - @result{} Event (35025468 deleted "/tmp/foo") +(write-region "bla" nil "/tmp/foo/bla") + @result{} Event (35025468 created "/tmp/foo/.#bla") + Event (35025468 created "/tmp/foo/bla") + Event (35025468 changed "/tmp/foo/bla") + Event (35025468 changed "/tmp/foo/.#bla") +@end group + +@group +;; Deleting a file in the directory doesn't invalidate the watch. +(delete-file "/tmp/foo/bla") + @result{} Event (35025468 deleted "/tmp/foo/bla") +@end group + +@group +(write-region "bla" nil "/tmp/foo/bla") + @result{} Event (35025468 created "/tmp/foo/.#bla") + Event (35025468 created "/tmp/foo/bla") + Event (35025468 changed "/tmp/foo/bla") + Event (35025468 changed "/tmp/foo/.#bla") +@end group + +@group +;; Deleting the directory invalidates the watch. +(delete-directory "/tmp/foo" 'recursive) + @result{} Event (35025468 deleted "/tmp/foo/bla") + Event (35025468 deleted "/tmp/foo") Event (35025468 stopped "/tmp/foo") @end group diff --git a/etc/images/icons/hicolor/scalable/apps/emacs.svg b/etc/images/icons/hicolor/scalable/apps/emacs.svg index 9de91c61c01..52742043f40 100644 --- a/etc/images/icons/hicolor/scalable/apps/emacs.svg +++ b/etc/images/icons/hicolor/scalable/apps/emacs.svg @@ -6,45 +6,19 @@ xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.0" - width="48" - height="48" - viewBox="0.171 0.201 512 512" - id="svg4768" xml:space="preserve" - inkscape:version="0.91 r13725" - sodipodi:docname="emacs.svg" - inkscape:export-filename="/home/nico/work/emacs/etc/images/icons/hicolor/16x16/apps/emacs.png" - inkscape:export-xdpi="30" - inkscape:export-ydpi="30"><metadata + id="svg4768" + viewBox="0.171 0.201 512 512" + height="48" + width="48" + version="1.0"><metadata id="metadata70"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="1600" - inkscape:window-height="836" - id="namedview68" - showgrid="false" - inkscape:zoom="6.9532167" - inkscape:cx="2.4213042" - inkscape:cy="30.151333" - inkscape:window-x="0" - inkscape:window-y="27" - inkscape:window-maximized="1" - inkscape:current-layer="svg4768" - showguides="true" - inkscape:guide-bbox="true" /><!-- Gnu Emacs Icon + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><!-- Gnu Emacs Icon Copyright (C) 2008-2015 Free Software Foundation, Inc. + Author: Nicolas Petton <nicolas@petton.fr> + This file is part of GNU Emacs. GNU Emacs is free software: you can redistribute it and/or modify @@ -62,259 +36,251 @@ --><!-- Created with Inkscape (http://www.inkscape.org/) --><defs id="defs4770"><linearGradient - inkscape:collect="always" id="linearGradient4292"><stop - style="stop-color:#411f5d;stop-opacity:1" + id="stop4294" offset="0" - id="stop4294" /><stop - style="stop-color:#5b2a85;stop-opacity:1" + style="stop-color:#411f5d;stop-opacity:1" /><stop + id="stop4296" offset="1" - id="stop4296" /></linearGradient><linearGradient + style="stop-color:#5b2a85;stop-opacity:1" /></linearGradient><linearGradient id="linearGradient4284"><stop - id="stop4286" + offset="0" style="stop-color:#8381c5;stop-opacity:1" - offset="0" /><stop - offset="0.56639391" + id="stop4286" /><stop + id="stop4290" style="stop-color:#7e55b3;stop-opacity:0.99607843" - id="stop4290" /><stop - id="stop4288" + offset="0.56639391" /><stop + offset="1" style="stop-color:#a52ecb;stop-opacity:0.99215686" - offset="1" /></linearGradient><linearGradient + id="stop4288" /></linearGradient><linearGradient id="linearGradient4898"><stop - offset="0" + id="stop4278" style="stop-color:#bab8db;stop-opacity:1" - id="stop4278" /><stop - offset="1" + offset="0" /><stop + id="stop4280" style="stop-color:#5955a9;stop-opacity:0.99159664" - id="stop4280" /></linearGradient><linearGradient + offset="1" /></linearGradient><linearGradient id="linearGradient3294"><stop - id="stop3296" + offset="0" style="stop-color:#6376e6;stop-opacity:1" - offset="0" /><stop - id="stop3302" + id="stop3296" /><stop + offset="0.50094414" style="stop-color:#222989;stop-opacity:1" - offset="0.50094414" /><stop - id="stop3298" + id="stop3302" /><stop + offset="1" style="stop-color:#00003d;stop-opacity:1" - offset="1" /></linearGradient><linearGradient + id="stop3298" /></linearGradient><linearGradient id="linearGradient3284"><stop - id="stop3286" + offset="0" style="stop-color:#000000;stop-opacity:1" - offset="0" /><stop - id="stop3292" + id="stop3286" /><stop + offset="0.84845906" style="stop-color:#000000;stop-opacity:0.49803922" - offset="0.84845906" /><stop - id="stop3288" + id="stop3292" /><stop + offset="1" style="stop-color:#000000;stop-opacity:0" - offset="1" /></linearGradient><linearGradient + id="stop3288" /></linearGradient><linearGradient id="linearGradient3274"><stop - id="stop3276" + offset="0" style="stop-color:#000000;stop-opacity:1" - offset="0" /><stop - id="stop3278" + id="stop3276" /><stop + offset="1" style="stop-color:#000000;stop-opacity:0" - offset="1" /></linearGradient><linearGradient + id="stop3278" /></linearGradient><linearGradient id="linearGradient3262"><stop - id="stop3264" + offset="0" style="stop-color:#000000;stop-opacity:1" - offset="0" /><stop - id="stop3266" + id="stop3264" /><stop + offset="1" style="stop-color:#000000;stop-opacity:0" - offset="1" /></linearGradient><linearGradient + id="stop3266" /></linearGradient><linearGradient id="linearGradient3242"><stop - id="stop3244" + offset="0" style="stop-color:#282828;stop-opacity:1" - offset="0" /><stop - id="stop3252" + id="stop3244" /><stop + offset="0.39253417" style="stop-color:#808080;stop-opacity:1" - offset="0.39253417" /><stop - id="stop3246" + id="stop3252" /><stop + offset="1" style="stop-color:#d9d9d9;stop-opacity:1" - offset="1" /></linearGradient><linearGradient + id="stop3246" /></linearGradient><linearGradient id="linearGradient3202"><stop - id="stop3204" + offset="0" style="stop-color:#2b2b2b;stop-opacity:1" - offset="0" /><stop - id="stop3250" + id="stop3204" /><stop + offset="0.5" style="stop-color:#828383;stop-opacity:1" - offset="0.5" /><stop - id="stop3206" + id="stop3250" /><stop + offset="1" style="stop-color:#dadbdb;stop-opacity:1" - offset="1" /></linearGradient><linearGradient + id="stop3206" /></linearGradient><linearGradient id="linearGradient4966"><stop - id="stop4968" + offset="0" style="stop-color:#b6b3d8;stop-opacity:1" - offset="0" /><stop - id="stop4970" + id="stop4968" /><stop + offset="1" style="stop-color:#b6b3d8;stop-opacity:0" - offset="1" /></linearGradient><linearGradient + id="stop4970" /></linearGradient><linearGradient id="linearGradient4938"><stop - id="stop4940" + offset="0" style="stop-color:#000000;stop-opacity:1" - offset="0" /><stop - id="stop4942" + id="stop4940" /><stop + offset="1" style="stop-color:#000000;stop-opacity:0" - offset="1" /></linearGradient><linearGradient + id="stop4942" /></linearGradient><linearGradient id="linearGradient4282"><stop - id="stop4900" + offset="0" style="stop-color:#bab8db;stop-opacity:1" - offset="0" /><stop - id="stop4902" + id="stop4900" /><stop + offset="1" style="stop-color:#5955a9;stop-opacity:0.99159664" - offset="1" /></linearGradient><linearGradient + id="stop4902" /></linearGradient><linearGradient id="linearGradient4876"><stop - id="stop4878" + offset="0" style="stop-color:#d3d2e8;stop-opacity:1" - offset="0" /><stop - id="stop4880" + id="stop4878" /><stop + offset="1" style="stop-color:#5955a9;stop-opacity:0.99159664" - offset="1" /></linearGradient><radialGradient - cx="20.951529" - cy="-108.96888" - r="266.76535" - fx="20.951529" - fy="-108.96888" - id="radialGradient4892" + id="stop4880" /></linearGradient><radialGradient + gradientTransform="matrix(0.6817439,0,0,0.5905355,-3.8523706,-28.935273)" + gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4898" + id="radialGradient4892" + fy="-108.96888" + fx="20.951529" + r="266.76535" + cy="-108.96888" + cx="20.951529" /><radialGradient + gradientTransform="matrix(1,0,0,0.1854103,0,383.88493)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.6817439,0,0,0.5905355,-3.8523706,-28.935273)" /><radialGradient - cx="233.8876" - cy="471.26172" - r="170.49393" - fx="233.8876" - fy="471.26172" - id="radialGradient4944" xlink:href="#linearGradient4938" + id="radialGradient4944" + fy="471.26172" + fx="233.8876" + r="170.49393" + cy="471.26172" + cx="233.8876" /><radialGradient + gradientTransform="matrix(1,0,0,0.9121621,0,32.654948)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,0.1854103,0,383.88493)" /><radialGradient - cx="299.70135" - cy="371.76376" - r="76.696358" - fx="299.70135" - fy="371.76376" - id="radialGradient4972" xlink:href="#linearGradient4966" + id="radialGradient4972" + fy="371.76376" + fx="299.70135" + r="76.696358" + cy="371.76376" + cx="299.70135" /><radialGradient + gradientTransform="matrix(0.414705,0.3300575,-0.5059004,0.6356454,346.95314,49.479585)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,0.9121621,0,32.654948)" /><radialGradient - cx="289.44067" - cy="390.45248" - r="17.67668" - fx="289.44067" - fy="390.45248" - id="radialGradient3210" xlink:href="#linearGradient3202" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.414705,0.3300575,-0.5059004,0.6356454,346.95314,49.479585)" /><radialGradient - cx="283.50717" - cy="382.14804" + id="radialGradient3210" + fy="390.45248" + fx="289.44067" r="17.67668" - fx="283.50717" - fy="382.14804" - id="radialGradient3238" + cy="390.45248" + cx="289.44067" /><radialGradient + gradientTransform="matrix(0.414705,0.3300575,-0.5059004,0.6356454,448.41009,-65.398074)" + gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3202" + id="radialGradient3238" + fy="382.14804" + fx="283.50717" + r="17.67668" + cy="382.14804" + cx="283.50717" /><radialGradient + gradientTransform="matrix(-6.5565014e-2,-5.9721765e-2,1.6871024,-1.8521705,171.90774,540.51473)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.414705,0.3300575,-0.5059004,0.6356454,448.41009,-65.398074)" /><radialGradient - cx="418.45551" - cy="181.18982" - r="63.068935" - fx="418.45551" - fy="181.18982" - id="radialGradient3248" xlink:href="#linearGradient3242" + id="radialGradient3248" + fy="181.18982" + fx="418.45551" + r="63.068935" + cy="181.18982" + cx="418.45551" /><radialGradient + gradientTransform="matrix(0.4055116,-3.3440123e-2,0.1034174,4.3988695,177.23251,-1191.6649)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(-6.5565014e-2,-5.9721765e-2,1.6871024,-1.8521705,171.90774,540.51473)" /><radialGradient - cx="354.51709" - cy="357.33591" - r="33.712105" - fx="354.51709" - fy="357.33591" - id="radialGradient3268" xlink:href="#linearGradient3262" + id="radialGradient3268" + fy="357.33591" + fx="354.51709" + r="33.712105" + cy="357.33591" + cx="354.51709" /><radialGradient + gradientTransform="matrix(-0.1339874,-0.1146812,0.3079048,-0.3597394,444.23592,395.03849)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.4055116,-3.3440123e-2,0.1034174,4.3988695,177.23251,-1191.6649)" /><radialGradient - cx="510.58469" - cy="223.55537" - r="132.28336" - fx="510.58469" - fy="223.55537" - id="radialGradient3280" xlink:href="#linearGradient3274" + id="radialGradient3280" + fy="223.55537" + fx="510.58469" + r="132.28336" + cy="223.55537" + cx="510.58469" /><radialGradient + gradientTransform="matrix(-1.2497569,1.3798305,-9.6289463e-2,-7.2974479e-2,674.3826,-70.590682)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(-0.1339874,-0.1146812,0.3079048,-0.3597394,444.23592,395.03849)" /><radialGradient - cx="284.4671" - cy="-158.17821" - r="110.2972" - fx="284.4671" - fy="-158.17821" - id="radialGradient3290" xlink:href="#linearGradient3284" + id="radialGradient3290" + fy="-158.17821" + fx="284.4671" + r="110.2972" + cy="-158.17821" + cx="284.4671" /><radialGradient + gradientTransform="matrix(-0.1008165,-8.0872321e-2,1.0745309,-1.3395252,13.843287,784.79288)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(-1.2497569,1.3798305,-9.6289463e-2,-7.2974479e-2,674.3826,-70.590682)" /><radialGradient - cx="425.51019" - cy="356.62274" - r="143.34167" - fx="425.51019" - fy="356.62274" - id="radialGradient3300" xlink:href="#linearGradient3294" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(-0.1008165,-8.0872321e-2,1.0745309,-1.3395252,13.843287,784.79288)" /><filter - inkscape:collect="always" - style="color-interpolation-filters:sRGB" - id="filter4350" - x="-0.044626798" - width="1.0892536" + id="radialGradient3300" + fy="356.62274" + fx="425.51019" + r="143.34167" + cy="356.62274" + cx="425.51019" /><filter + height="1.088351" y="-0.044175496" - height="1.088351"><feGaussianBlur - inkscape:collect="always" - stdDeviation="8.7848425" - id="feGaussianBlur4352" /></filter><linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4284" - id="linearGradient4245" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.87385837,0,0,0.82818057,246.00762,250.28138)" - spreadMethod="pad" - x1="-122.20192" - y1="-161.8512" + width="1.0892536" + x="-0.044626798" + id="filter4350" + style="color-interpolation-filters:sRGB"><feGaussianBlur + id="feGaussianBlur4352" + stdDeviation="8.7848425" /></filter><linearGradient + y2="300.73987" x2="236.61363" - y2="300.73987" /><linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4292" - id="linearGradient4247" + y1="-161.8512" + x1="-122.20192" + spreadMethod="pad" + gradientTransform="matrix(0.87385837,0,0,0.82818057,246.00762,250.28138)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.98684959,0,0,0.98684959,3.0344187,2.5250397)" - x1="447.80933" - y1="396.6066" + id="linearGradient4245" + xlink:href="#linearGradient4284" /><linearGradient + y2="66.018341" x2="173.94518" - y2="66.018341" /></defs><rect - width="512" - height="512" - x="0.171" - y="0.20100001" + y1="396.6066" + x1="447.80933" + gradientTransform="matrix(0.98684959,0,0,0.98684959,3.0344187,2.5250397)" + gradientUnits="userSpaceOnUse" + id="linearGradient4247" + xlink:href="#linearGradient4292" /></defs><rect + style="fill:none;display:none" id="rect4772" - style="fill:none;display:none" /><g - id="g4788" - style="display:none"><g - id="g4790" - style="display:inline" /></g><g - id="g4806" - style="display:none"><g - id="g4808" - style="display:inline"><path - d="M 349.098,256.651 C 348.833,256.397 386.735,284.256 388.519,281.663 C 394.881,272.411 470.565,188.526 473.303,165.427 C 473.545,163.424 472.787,161.331 472.787,161.331 C 472.787,161.331 471.597,161.187 466.462,157.017 C 463.77,154.825 460.979,152.436 460.979,152.436 C 444.925,153.434 403.094,193.995 349.917,256.004" + y="0.20100001" + x="0.171" + height="512" + width="512" /><g + style="display:none" + id="g4788"><g + style="display:inline" + id="g4790" /></g><g + style="display:none" + id="g4806"><g + style="display:inline" + id="g4808"><path + style="fill:#050505;display:none" id="path4810" - style="fill:#050505;display:none" /></g></g><path - transform="matrix(0.98684957,0,0,0.98684957,3.0344041,2.5250397)" - d="m 491.66937,257.75916 c 0,131.79436 -105.76,238.63481 -236.22155,238.63481 -130.46155,0 -236.221539,-106.84045 -236.221539,-238.63481 0,-131.79437 105.759989,-238.634808 236.221539,-238.634808 130.46155,0 236.22155,106.840438 236.22155,238.634808 z" - id="path4233" + d="M 349.098,256.651 C 348.833,256.397 386.735,284.256 388.519,281.663 C 394.881,272.411 470.565,188.526 473.303,165.427 C 473.545,163.424 472.787,161.331 472.787,161.331 C 472.787,161.331 471.597,161.187 466.462,157.017 C 463.77,154.825 460.979,152.436 460.979,152.436 C 444.925,153.434 403.094,193.995 349.917,256.004" /></g></g><path style="opacity:0.40500004;fill:#211f46;fill-opacity:0.99607843;stroke:#0a0b1b;stroke-width:8.53333378;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4350)" - inkscape:connector-curvature="0" /><path - inkscape:connector-curvature="0" - style="opacity:1;fill:url(#linearGradient4245);fill-opacity:1;stroke:url(#linearGradient4247);stroke-width:13.33816814;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path4233" + d="m 491.66937,257.75916 c 0,131.79436 -105.76,238.63481 -236.22155,238.63481 -130.46155,0 -236.221539,-106.84045 -236.221539,-238.63481 0,-131.79437 105.759989,-238.634808 236.221539,-238.634808 130.46155,0 236.22155,106.840438 236.22155,238.634808 z" + transform="matrix(0.98684957,0,0,0.98684957,3.0344041,2.5250397)" /><path + d="m 488.23812,256.89456 c 0,130.06121 -104.3692,235.49665 -233.1151,235.49665 -128.7459,0 -233.115201,-105.43544 -233.115201,-235.49665 0,-130.06123 104.369301,-235.49666 233.115201,-235.49666 128.7459,0 233.1151,105.43543 233.1151,235.49666 z" id="path4235" - d="m 488.23812,256.89456 c 0,130.06121 -104.3692,235.49665 -233.1151,235.49665 -128.7459,0 -233.115201,-105.43544 -233.115201,-235.49665 0,-130.06123 104.369301,-235.49666 233.115201,-235.49666 128.7459,0 233.1151,105.43543 233.1151,235.49666 z" /><path - inkscape:connector-curvature="0" - style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + style="opacity:1;fill:url(#linearGradient4245);fill-opacity:1;stroke:url(#linearGradient4247);stroke-width:13.33816814;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path + d="m 175.0003,422.31057 c 0,0 19.7385,1.39634 45.1312,-0.84159 10.2834,-0.9063 49.3267,-4.74128 78.5169,-11.14289 0,0 35.5899,-7.61669 54.6301,-14.63335 19.9225,-7.34185 30.7636,-13.57304 35.6433,-22.40243 -0.2128,-1.80907 1.5024,-8.22438 -7.685,-12.07788 -23.4887,-9.85199 -50.73,-8.06998 -104.6338,-9.21285 -59.7772,-2.05391 -79.6627,-12.05971 -90.2556,-20.11838 -10.1579,-8.17519 -5.05,-30.79254 38.4742,-50.71499 21.9244,-10.60898 107.8705,-30.18698 107.8705,-30.18698 -28.9451,-14.30725 -82.9186,-39.45893 -94.0134,-44.89023 -9.7308,-4.76348 -25.303,-11.93595 -28.6785,-20.61368 -3.8271,-8.33089 9.0383,-15.50726 16.2248,-17.56236 23.1448,-6.67602 55.8182,-10.82538 85.5548,-11.29122 14.9472,-0.23417 17.3734,-1.19586 17.3734,-1.19586 20.6243,-3.42116 34.2014,-17.53175 28.5446,-39.87876 -5.0783,-22.81046 -31.8617,-36.21365 -57.3138,-31.57361 -23.9682,4.36956 -81.7378,21.15007 -81.7378,21.15007 71.4075,-0.61803 83.3592,0.57378 88.697,8.03676 3.1523,4.40742 -1.4324,10.45068 -20.4765,13.56099 -20.733,3.38616 -63.8312,7.46399 -63.8312,7.46399 -41.3449,2.4554 -70.4682,2.61974 -79.203,21.11314 -5.7065,12.08196 6.0854,22.7633 11.2538,29.4493 21.8407,24.28905 53.3882,37.38879 73.6948,47.03553 7.6405,3.62963 30.0586,10.48407 30.0586,10.48407 -65.8782,-3.62335 -113.4003,16.6055 -141.2764,39.89622 -31.5288,29.16261 -17.581403,63.92354 47.0124,85.3268 38.1517,12.6416 57.0725,18.58695 113.9815,13.46232 33.52,-1.80673 38.8041,-0.73155 39.1383,2.01892 0.4705,3.87242 -37.2311,13.49165 -47.524,16.4606 -26.1853,7.55306 -94.8276,22.80438 -95.1712,22.87835 z" id="path4237" - d="m 175.0003,422.31057 c 0,0 19.7385,1.39634 45.1312,-0.84159 10.2834,-0.9063 49.3267,-4.74128 78.5169,-11.14289 0,0 35.5899,-7.61669 54.6301,-14.63335 19.9225,-7.34185 30.7636,-13.57304 35.6433,-22.40243 -0.2128,-1.80907 1.5024,-8.22438 -7.685,-12.07788 -23.4887,-9.85199 -50.73,-8.06998 -104.6338,-9.21285 -59.7772,-2.05391 -79.6627,-12.05971 -90.2556,-20.11838 -10.1579,-8.17519 -5.05,-30.79254 38.4742,-50.71499 21.9244,-10.60898 107.8705,-30.18698 107.8705,-30.18698 -28.9451,-14.30725 -82.9186,-39.45893 -94.0134,-44.89023 -9.7308,-4.76348 -25.303,-11.93595 -28.6785,-20.61368 -3.8271,-8.33089 9.0383,-15.50726 16.2248,-17.56236 23.1448,-6.67602 55.8182,-10.82538 85.5548,-11.29122 14.9472,-0.23417 17.3734,-1.19586 17.3734,-1.19586 20.6243,-3.42116 34.2014,-17.53175 28.5446,-39.87876 -5.0783,-22.81046 -31.8617,-36.21365 -57.3138,-31.57361 -23.9682,4.36956 -81.7378,21.15007 -81.7378,21.15007 71.4075,-0.61803 83.3592,0.57378 88.697,8.03676 3.1523,4.40742 -1.4324,10.45068 -20.4765,13.56099 -20.733,3.38616 -63.8312,7.46399 -63.8312,7.46399 -41.3449,2.4554 -70.4682,2.61974 -79.203,21.11314 -5.7065,12.08196 6.0854,22.7633 11.2538,29.4493 21.8407,24.28905 53.3882,37.38879 73.6948,47.03553 7.6405,3.62963 30.0586,10.48407 30.0586,10.48407 -65.8782,-3.62335 -113.4003,16.6055 -141.2764,39.89622 -31.5288,29.16261 -17.581403,63.92354 47.0124,85.3268 38.1517,12.6416 57.0725,18.58695 113.9815,13.46232 33.52,-1.80673 38.8041,-0.73155 39.1383,2.01892 0.4705,3.87242 -37.2311,13.49165 -47.524,16.4606 -26.1853,7.55306 -94.8276,22.80438 -95.1712,22.87835 z" /></svg>
\ No newline at end of file + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /></svg> diff --git a/lisp/autorevert.el b/lisp/autorevert.el index 37ee8eedcfd..f0c12d2d97e 100644 --- a/lisp/autorevert.el +++ b/lisp/autorevert.el @@ -570,37 +570,54 @@ no more reverts are possible until the next call of ;; Since we watch a directory, a file name must be returned. (cl-assert (stringp file)) (when (eq action 'renamed) (cl-assert (stringp file1))) - ;; Loop over all buffers, in order to find the intended one. - (cl-dolist (buffer buffers) - (when (buffer-live-p buffer) - (with-current-buffer buffer - (when (or - ;; A buffer associated with a file. - (and (stringp buffer-file-name) - (or - (and (memq action '(attribute-changed changed created)) - (string-equal - (file-name-nondirectory file) - (file-name-nondirectory buffer-file-name))) - (and (eq action 'renamed) - (string-equal - (file-name-nondirectory file1) - (file-name-nondirectory buffer-file-name))))) - ;; A buffer w/o a file, like dired. - (and (null buffer-file-name) - (memq action '(created renamed deleted)))) - ;; Mark buffer modified. - (setq auto-revert-notify-modified-p t) - - ;; Revert the buffer now if we're not locked out. - (when (/= auto-revert-buffers-counter-lockedout - auto-revert-buffers-counter) - (auto-revert-handler) - (setq auto-revert-buffers-counter-lockedout - auto-revert-buffers-counter)) - - ;; No need to check other buffers. - (cl-return)))))))) + + (if (eq action 'stopped) + ;; File notification has stopped. Continue with polling. + (cl-dolist (buffer buffers) + (with-current-buffer buffer + (when (or + ;; A buffer associated with a file. + (and (stringp buffer-file-name) + (string-equal + (file-name-nondirectory file) + (file-name-nondirectory buffer-file-name))) + ;; A buffer w/o a file, like dired. + (null buffer-file-name)) + (auto-revert-notify-rm-watch) + (setq-local auto-revert-use-notify nil)))) + + ;; Loop over all buffers, in order to find the intended one. + (cl-dolist (buffer buffers) + (when (buffer-live-p buffer) + (with-current-buffer buffer + (when (or + ;; A buffer associated with a file. + (and (stringp buffer-file-name) + (or + (and (memq + action '(attribute-changed changed created)) + (string-equal + (file-name-nondirectory file) + (file-name-nondirectory buffer-file-name))) + (and (eq action 'renamed) + (string-equal + (file-name-nondirectory file1) + (file-name-nondirectory buffer-file-name))))) + ;; A buffer w/o a file, like dired. + (and (null buffer-file-name) + (memq action '(created renamed deleted)))) + ;; Mark buffer modified. + (setq auto-revert-notify-modified-p t) + + ;; Revert the buffer now if we're not locked out. + (when (/= auto-revert-buffers-counter-lockedout + auto-revert-buffers-counter) + (auto-revert-handler) + (setq auto-revert-buffers-counter-lockedout + auto-revert-buffers-counter)) + + ;; No need to check other buffers. + (cl-return))))))))) (defun auto-revert-active-p () "Check if auto-revert is active (in current buffer or globally)." diff --git a/lisp/cedet/cedet-global.el b/lisp/cedet/cedet-global.el index 3773ba09f32..3ceed5d3b54 100644 --- a/lisp/cedet/cedet-global.el +++ b/lisp/cedet/cedet-global.el @@ -97,7 +97,7 @@ SCOPE is the scope of the search, such as 'project or 'subdirs." ;; Check for warnings. (with-current-buffer b (goto-char (point-min)) - (when (re-search-forward "Error\\|Warning" nil t) + (when (re-search-forward "Error\\|Warning\\|invalid" nil t) (error "Output:\n%S" (buffer-string)))) b)) @@ -186,12 +186,14 @@ If a database already exists, then just update it." (let ((root (cedet-gnu-global-root dir))) (if root (setq dir root)) (let ((default-directory dir)) - (cedet-gnu-global-gtags-call - (when root - '("-u");; Incremental update flag. - )) - ) - )) + (if root + ;; Incremental update. This can be either "gtags -i" or + ;; "global -u"; the gtags manpage says it's better to use + ;; "global -u". + (cedet-gnu-global-call (list "-u")) + (cedet-gnu-global-gtags-call nil) + ) + ))) (provide 'cedet-global) diff --git a/lisp/cedet/ede/generic.el b/lisp/cedet/ede/generic.el index b865ff5028d..d3be545a158 100644 --- a/lisp/cedet/ede/generic.el +++ b/lisp/cedet/ede/generic.el @@ -303,7 +303,7 @@ CLASS is the EIEIO class that is used to track this project. It should subclass (ede-generic-new-autoloader "generic-cvs" "Generic CVS" "CVS" 'ede-generic-vc-project) (ede-generic-new-autoloader "generic-mtn" "Generic Monotone" - "_MTN/options" 'ede-generic-vc-project) + "_MTN" 'ede-generic-vc-project) ;; Take advantage of existing 'projectile' based projects. ;; @TODO - if projectile supports compile commands etc, can we diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index 2eba0216faf..21c1f1be394 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -64,7 +64,7 @@ (require 'ewoc) (require 'find-func) (require 'help) - +(require 'pp) ;;; UI customization options. @@ -1300,7 +1300,8 @@ EXPECTEDP specifies whether the result was expected." (defun ert--pp-with-indentation-and-newline (object) "Pretty-print OBJECT, indenting it to the current column of point. Ensures a final newline is inserted." - (let ((begin (point))) + (let ((begin (point)) + (pp-escape-newlines nil)) (pp object (current-buffer)) (unless (bolp) (insert "\n")) (save-excursion diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el index cc437e02e78..5ef51f12d96 100644 --- a/lisp/emacs-lisp/map.el +++ b/lisp/emacs-lisp/map.el @@ -45,12 +45,12 @@ (require 'seq) (pcase-defmacro map (&rest args) - "pcase pattern matching map elements. + "Build a `pcase' pattern matching map elements. -Matches if the object is a map (list, hash-table or array), and -each PATTERN matches the corresponding elements of the map. +The `pcase' pattern will match each element of PATTERN against +the corresponding elements of the map. -Supernumerary elements of the map are ignored if fewer ARGS are +Extra elements of the map are ignored if fewer ARGS are given, and the match does not fail. ARGS can be a list of the form (KEY PAT), in which case KEY in an @@ -92,7 +92,7 @@ Return RESULT if non-nil or the result of evaluation of the form." (t (error "Unsupported map: %s" ,map-var))))) (defun map-elt (map key &optional default) - "Perform a lookup in MAP of KEY and return its associated value. + "Lookup KEY in MAP and return its associated value. If KEY is not found, return DEFAULT which defaults to nil. If MAP is a list, `eql' is used to lookup KEY. @@ -122,7 +122,7 @@ MAP can be a list, hash-table or array." default))) (defmacro map-put (map key value) - "In MAP, associate KEY with VALUE and return MAP. + "Associate KEY with VALUE in MAP and return MAP. If KEY is already present in MAP, replace the associated value with VALUE. @@ -133,8 +133,9 @@ MAP can be a list, hash-table or array." ,map))) (defmacro map-delete (map key) - "In MAP, delete the key KEY if present and return MAP. -If MAP is an array, store nil at the index KEY. + "Delete KEY from MAP and return MAP. +No error is signaled if KEY is not a key of MAP. If MAP is an +array, store nil at the index KEY. MAP can be a list, hash-table or array." (declare (debug t)) @@ -245,7 +246,7 @@ MAP can be a list, hash-table or array." (arrayp map))) (defun map-empty-p (map) - "Return non-nil is MAP is empty. + "Return non-nil if MAP is empty. MAP can be a list, hash-table or array." (map--dispatch map @@ -254,7 +255,7 @@ MAP can be a list, hash-table or array." :hash-table (zerop (hash-table-count map)))) (defun map-contains-key (map key &optional testfn) - "Return non-nil if MAP contain the key KEY, nil otherwise. + "Return non-nil if MAP contain KEY, nil otherwise. Equality is defined by TESTFN if non-nil or by `equal' if nil. MAP can be a list, hash-table or array." @@ -284,7 +285,7 @@ MAP can be a list, hash-table or array." t)) (defun map-merge (type &rest maps) - "Merge into a map of type TYPE all the key/value pairs in the maps MAPS. + "Merge into a map of type TYPE all the key/value pairs in MAPS. MAP can be a list, hash-table or array." (let (result) diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index f5189c7dc97..d0c2d24b015 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -61,305 +61,310 @@ (defmacro seq-doseq (spec &rest body) "Loop over a sequence. -Similar to `dolist' but can be applied to lists, strings, and vectors. +Evaluate BODY with VAR bound to each element of SEQUENCE, in turn. -Evaluate BODY with VAR bound to each element of SEQ, in turn. +Similar to `dolist' but can be applied to lists, strings, and vectors. -\(fn (VAR SEQ) BODY...)" +\(fn (VAR SEQUENCE) BODY...)" (declare (indent 1) (debug ((symbolp form &optional form) body))) `(seq-do (lambda (,(car spec)) ,@body) ,(cadr spec))) (pcase-defmacro seq (&rest patterns) - "pcase pattern matching sequence elements. + "Build a `pcase' pattern that matches elements of SEQUENCE. -Matches if the object is a sequence (list, string or vector), and -each PATTERN matches the corresponding element of the sequence. +The `pcase' pattern will match each element of PATTERNS against the +corresponding element of SEQUENCE. -Supernumerary elements of the sequence are ignored if fewer -PATTERNS are given, and the match does not fail." +Extra elements of the sequence are ignored if fewer PATTERNS are +given, and the match does not fail." `(and (pred seq-p) ,@(seq--make-pcase-bindings patterns))) -(defmacro seq-let (args seq &rest body) - "Bind the variables in ARGS to the elements of SEQ then evaluate BODY. +(defmacro seq-let (args sequence &rest body) + "Bind the variables in ARGS to the elements of SEQUENCE, then evaluate BODY. ARGS can also include the `&rest' marker followed by a variable -name to be bound to the rest of SEQ." +name to be bound to the rest of SEQUENCE." (declare (indent 2) (debug t)) - `(pcase-let ((,(seq--make-pcase-patterns args) ,seq)) + `(pcase-let ((,(seq--make-pcase-patterns args) ,sequence)) ,@body)) -;;; Basic seq functions that have to be implemented by new seq types -(cl-defgeneric seq-elt (seq n) - "Return the element of SEQ at index N." - (elt seq n)) +;;; Basic seq functions that have to be implemented by new sequence types +(cl-defgeneric seq-elt (sequence n) + "Return Nth element of SEQUENCE." + (elt sequence n)) ;; Default gv setters for `seq-elt'. ;; It can be a good idea for new sequence implementations to provide a ;; "gv-setter" for `seq-elt'. -(cl-defmethod (setf seq-elt) (store (seq array) n) - (aset seq n store)) +(cl-defmethod (setf seq-elt) (store (sequence array) n) + (aset sequence n store)) -(cl-defmethod (setf seq-elt) (store (seq cons) n) - (setcar (nthcdr n seq) store)) +(cl-defmethod (setf seq-elt) (store (sequence cons) n) + (setcar (nthcdr n sequence) store)) -(cl-defgeneric seq-length (seq) - "Return the length of the sequence SEQ." - (length seq)) +(cl-defgeneric seq-length (sequence) + "Return the number of elements of SEQUENCE." + (length sequence)) -(cl-defgeneric seq-do (function seq) - "Apply FUNCTION to each element of SEQ, presumably for side effects. -Return SEQ." - (mapc function seq)) +(cl-defgeneric seq-do (function sequence) + "Apply FUNCTION to each element of SEQUENCE, presumably for side effects. +Return SEQUENCE." + (mapc function sequence)) (defalias 'seq-each #'seq-do) -(cl-defgeneric seq-p (seq) - "Return non-nil if SEQ is a sequence, nil otherwise." - (sequencep seq)) +(cl-defgeneric seq-p (sequence) + "Return non-nil if SEQUENCE is a sequence, nil otherwise." + (sequencep sequence)) -(cl-defgeneric seq-copy (seq) - "Return a shallow copy of SEQ." - (copy-sequence seq)) +(cl-defgeneric seq-copy (sequence) + "Return a shallow copy of SEQUENCE." + (copy-sequence sequence)) -(cl-defgeneric seq-subseq (seq start &optional end) - "Return the subsequence of SEQ from START to END. -If END is omitted, it defaults to the length of the sequence. -If START or END is negative, it counts from the end. -Signal an error if START or END are outside of the sequence (i.e -too large if positive or too small if negative)." - (cl-subseq seq start end)) +(cl-defgeneric seq-subseq (sequence start &optional end) + "Return the sequence of elements of SEQUENCE from START to END. +END is inclusive. + +If END is omitted, it defaults to the length of the sequence. If +START or END is negative, it counts from the end. Signal an +error if START or END are outside of the sequence (i.e too large +if positive or too small if negative)." + (cl-subseq sequence start end)) -(cl-defgeneric seq-map (function seq) - "Return the result of applying FUNCTION to each element of SEQ." +(cl-defgeneric seq-map (function sequence) + "Return the result of applying FUNCTION to each element of SEQUENCE." (let (result) (seq-do (lambda (elt) (push (funcall function elt) result)) - seq) + sequence) (nreverse result))) ;; faster implementation for sequences (sequencep) -(cl-defmethod seq-map (function (seq sequence)) - (mapcar function seq)) +(cl-defmethod seq-map (function (sequence sequence)) + (mapcar function sequence)) -(cl-defgeneric seq-drop (seq n) - "Return a subsequence of SEQ without its first N elements. -The result is a sequence of the same type as SEQ. +(cl-defgeneric seq-drop (sequence n) + "Remove the first N elements of SEQUENCE and return the result. +The result is a sequence of the same type as SEQUENCE. -If N is a negative integer or zero, SEQ is returned." +If N is a negative integer or zero, SEQUENCE is returned." (if (<= n 0) - seq - (let ((length (seq-length seq))) - (seq-subseq seq (min n length) length)))) + sequence + (let ((length (seq-length sequence))) + (seq-subseq sequence (min n length) length)))) -(cl-defgeneric seq-take (seq n) - "Return a subsequence of SEQ with its first N elements. -The result is a sequence of the same type as SEQ. +(cl-defgeneric seq-take (sequence n) + "Take the first N elements of SEQUENCE and return the result. +The result is a sequence of the same type as SEQUENCE. If N is a negative integer or zero, an empty sequence is returned." - (seq-subseq seq 0 (min (max n 0) (seq-length seq)))) - -(cl-defgeneric seq-drop-while (pred seq) - "Return a sequence from the first element for which (PRED element) is nil in SEQ. -The result is a sequence of the same type as SEQ." - (seq-drop seq (seq--count-successive pred seq))) - -(cl-defgeneric seq-take-while (pred seq) - "Return the successive elements for which (PRED element) is non-nil in SEQ. -The result is a sequence of the same type as SEQ." - (seq-take seq (seq--count-successive pred seq))) - -(cl-defgeneric seq-empty-p (seq) - "Return non-nil if the sequence SEQ is empty, nil otherwise." - (= 0 (seq-length seq))) - -(cl-defgeneric seq-sort (pred seq) - "Return a sorted sequence comparing using PRED the elements of SEQ. -The result is a sequence of the same type as SEQ." - (let ((result (seq-sort pred (append seq nil)))) - (seq-into result (type-of seq)))) + (seq-subseq sequence 0 (min (max n 0) (seq-length sequence)))) + +(cl-defgeneric seq-drop-while (pred sequence) + "Remove the successive elements of SEQUENCE for which PRED returns non-nil. +PRED is a function of one argument. The result is a sequence of +the same type as SEQUENCE." + (seq-drop sequence (seq--count-successive pred sequence))) + +(cl-defgeneric seq-take-while (pred sequence) + "Take the successive elements of SEQUENCE for which PRED returns non-nil. +PRED is a function of one argument. The result is a sequence of +the same type as SEQUENCE." + (seq-take sequence (seq--count-successive pred sequence))) + +(cl-defgeneric seq-empty-p (sequence) + "Return non-nil if the SEQUENCE is empty, nil otherwise." + (= 0 (seq-length sequence))) + +(cl-defgeneric seq-sort (pred sequence) + "Sort SEQUENCE using PRED as comparison function. +The result is a sequence of the same type as SEQUENCE." + (let ((result (seq-sort pred (append sequence nil)))) + (seq-into result (type-of sequence)))) (cl-defmethod seq-sort (pred (list list)) (sort (seq-copy list) pred)) -(cl-defgeneric seq-reverse (seq) - "Return the reversed shallow copy of SEQ." +(cl-defgeneric seq-reverse (sequence) + "Return a sequence with elements of SEQUENCE in reverse order." (let ((result '())) (seq-map (lambda (elt) (push elt result)) - seq) - (seq-into result (type-of seq)))) + sequence) + (seq-into result (type-of sequence)))) ;; faster implementation for sequences (sequencep) -(cl-defmethod seq-reverse ((seq sequence)) - (reverse seq)) +(cl-defmethod seq-reverse ((sequence sequence)) + (reverse sequence)) -(cl-defgeneric seq-concatenate (type &rest seqs) - "Concatenate, into a sequence of type TYPE, the sequences SEQS. +(cl-defgeneric seq-concatenate (type &rest sequences) + "Concatenate SEQUENCES into a single sequence of type TYPE. TYPE must be one of following symbols: vector, string or list. \n(fn TYPE SEQUENCE...)" - (apply #'cl-concatenate type (seq-map #'seq-into-sequence seqs))) + (apply #'cl-concatenate type (seq-map #'seq-into-sequence sequences))) -(cl-defgeneric seq-into-sequence (seq) - "Convert SEQ into a sequence. +(cl-defgeneric seq-into-sequence (sequence) + "Convert SEQUENCE into a sequence. -The default implementation is to signal an error if SEQ is not a +The default implementation is to signal an error if SEQUENCE is not a sequence, specific functions should be implemented for new types -of seq." - (unless (sequencep seq) - (error "Cannot convert %S into a sequence" seq)) - seq) - -(cl-defgeneric seq-into (seq type) - "Convert the sequence SEQ into a sequence of type TYPE. -TYPE can be one of the following symbols: vector, string or list." +of sequence." + (unless (sequencep sequence) + (error "Cannot convert %S into a sequence" sequence)) + sequence) + +(cl-defgeneric seq-into (sequence type) + "Concatenate the elements of SEQUENCE into a sequence of type TYPE. +TYPE can be one of the following symbols: vector, string or +list." (pcase type - (`vector (vconcat seq)) - (`string (concat seq)) - (`list (append seq nil)) + (`vector (vconcat sequence)) + (`string (concat sequence)) + (`list (append sequence nil)) (_ (error "Not a sequence type name: %S" type)))) -(cl-defgeneric seq-filter (pred seq) - "Return a list of all the elements for which (PRED element) is non-nil in SEQ." +(cl-defgeneric seq-filter (pred sequence) + "Return a list of all the elements for which (PRED element) is non-nil in SEQUENCE." (let ((exclude (make-symbol "exclude"))) (delq exclude (seq-map (lambda (elt) (if (funcall pred elt) elt exclude)) - seq)))) + sequence)))) -(cl-defgeneric seq-remove (pred seq) - "Return a list of all the elements for which (PRED element) is nil in SEQ." +(cl-defgeneric seq-remove (pred sequence) + "Return a list of all the elements for which (PRED element) is nil in SEQUENCE." (seq-filter (lambda (elt) (not (funcall pred elt))) - seq)) + sequence)) -(cl-defgeneric seq-reduce (function seq initial-value) - "Reduce the function FUNCTION across SEQ, starting with INITIAL-VALUE. +(cl-defgeneric seq-reduce (function sequence initial-value) + "Reduce the function FUNCTION across SEQUENCE, starting with INITIAL-VALUE. Return the result of calling FUNCTION with INITIAL-VALUE and the -first element of SEQ, then calling FUNCTION with that result and -the second element of SEQ, then with that result and the third -element of SEQ, etc. +first element of SEQUENCE, then calling FUNCTION with that result and +the second element of SEQUENCE, then with that result and the third +element of SEQUENCE, etc. -If SEQ is empty, return INITIAL-VALUE and FUNCTION is not called." - (if (seq-empty-p seq) +If SEQUENCE is empty, return INITIAL-VALUE and FUNCTION is not called." + (if (seq-empty-p sequence) initial-value (let ((acc initial-value)) - (seq-doseq (elt seq) + (seq-doseq (elt sequence) (setq acc (funcall function acc elt))) acc))) -(cl-defgeneric seq-every-p (pred seq) - "Return non-nil if (PRED element) is non-nil for all elements of the sequence SEQ." +(cl-defgeneric seq-every-p (pred sequence) + "Return non-nil if (PRED element) is non-nil for all elements of SEQUENCE." (catch 'seq--break - (seq-doseq (elt seq) + (seq-doseq (elt sequence) (or (funcall pred elt) (throw 'seq--break nil))) t)) -(cl-defgeneric seq-some (pred seq) - "Return the first value for which if (PRED element) is non-nil for in SEQ." +(cl-defgeneric seq-some (pred sequence) + "Return the first value for which if (PRED element) is non-nil for in SEQUENCE." (catch 'seq--break - (seq-doseq (elt seq) + (seq-doseq (elt sequence) (let ((result (funcall pred elt))) (when result (throw 'seq--break result)))) nil)) -(cl-defgeneric seq-find (pred seq &optional default) - "Return the first element for which (PRED element) is non-nil in SEQ. +(cl-defgeneric seq-find (pred sequence &optional default) + "Return the first element for which (PRED element) is non-nil in SEQUENCE. If no element is found, return DEFAULT. Note that `seq-find' has an ambiguity if the found element is identical to DEFAULT, as it cannot be known if an element was found or not." (catch 'seq--break - (seq-doseq (elt seq) + (seq-doseq (elt sequence) (when (funcall pred elt) (throw 'seq--break elt))) default)) -(cl-defgeneric seq-count (pred seq) - "Return the number of elements for which (PRED element) is non-nil in SEQ." +(cl-defgeneric seq-count (pred sequence) + "Return the number of elements for which (PRED element) is non-nil in SEQUENCE." (let ((count 0)) - (seq-doseq (elt seq) + (seq-doseq (elt sequence) (when (funcall pred elt) (setq count (+ 1 count)))) count)) -(cl-defgeneric seq-contains (seq elt &optional testfn) - "Return the first element in SEQ that is equal to ELT. +(cl-defgeneric seq-contains (sequence elt &optional testfn) + "Return the first element in SEQUENCE that is equal to ELT. Equality is defined by TESTFN if non-nil or by `equal' if nil." (seq-some (lambda (e) (funcall (or testfn #'equal) elt e)) - seq)) + sequence)) -(cl-defgeneric seq-position (seq elt &optional testfn) - "Return the index of the first element in SEQ that is equal to ELT. +(cl-defgeneric seq-position (sequence elt &optional testfn) + "Return the index of the first element in SEQUENCE that is equal to ELT. Equality is defined by TESTFN if non-nil or by `equal' if nil." (let ((index 0)) (catch 'seq--break - (seq-doseq (e seq) + (seq-doseq (e sequence) (when (funcall (or testfn #'equal) e elt) (throw 'seq--break index)) (setq index (1+ index))) nil))) -(cl-defgeneric seq-uniq (seq &optional testfn) - "Return a list of the elements of SEQ with duplicates removed. +(cl-defgeneric seq-uniq (sequence &optional testfn) + "Return a list of the elements of SEQUENCE with duplicates removed. TESTFN is used to compare elements, or `equal' if TESTFN is nil." (let ((result '())) - (seq-doseq (elt seq) + (seq-doseq (elt sequence) (unless (seq-contains result elt testfn) (setq result (cons elt result)))) (nreverse result))) -(cl-defgeneric seq-mapcat (function seq &optional type) - "Concatenate the result of applying FUNCTION to each element of SEQ. +(cl-defgeneric seq-mapcat (function sequence &optional type) + "Concatenate the result of applying FUNCTION to each element of SEQUENCE. The result is a sequence of type TYPE, or a list if TYPE is nil." (apply #'seq-concatenate (or type 'list) - (seq-map function seq))) + (seq-map function sequence))) -(cl-defgeneric seq-partition (seq n) - "Return a list of the elements of SEQ grouped into sub-sequences of length N. +(cl-defgeneric seq-partition (sequence n) + "Return a list of the elements of SEQUENCE grouped into sub-sequences of length N. The last sequence may contain less than N elements. If N is a negative integer or 0, nil is returned." (unless (< n 1) (let ((result '())) - (while (not (seq-empty-p seq)) - (push (seq-take seq n) result) - (setq seq (seq-drop seq n))) + (while (not (seq-empty-p sequence)) + (push (seq-take sequence n) result) + (setq sequence (seq-drop sequence n))) (nreverse result)))) -(cl-defgeneric seq-intersection (seq1 seq2 &optional testfn) - "Return a list of the elements that appear in both SEQ1 and SEQ2. +(cl-defgeneric seq-intersection (sequence1 sequence2 &optional testfn) + "Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2. Equality is defined by TESTFN if non-nil or by `equal' if nil." (seq-reduce (lambda (acc elt) - (if (seq-contains seq2 elt testfn) + (if (seq-contains sequence2 elt testfn) (cons elt acc) acc)) - (seq-reverse seq1) + (seq-reverse sequence1) '())) -(cl-defgeneric seq-difference (seq1 seq2 &optional testfn) - "Return a list of the elements that appear in SEQ1 but not in SEQ2. +(cl-defgeneric seq-difference (sequence1 sequence2 &optional testfn) + "Return a list of the elements that appear in SEQUENCE1 but not in SEQUENCE2. Equality is defined by TESTFN if non-nil or by `equal' if nil." (seq-reduce (lambda (acc elt) - (if (not (seq-contains seq2 elt testfn)) + (if (not (seq-contains sequence2 elt testfn)) (cons elt acc) acc)) - (seq-reverse seq1) + (seq-reverse sequence1) '())) -(cl-defgeneric seq-group-by (function seq) - "Apply FUNCTION to each element of SEQ. -Separate the elements of SEQ into an alist using the results as +(cl-defgeneric seq-group-by (function sequence) + "Apply FUNCTION to each element of SEQUENCE. +Separate the elements of SEQUENCE into an alist using the results as keys. Keys are compared using `equal'." (seq-reduce (lambda (acc elt) @@ -369,25 +374,25 @@ keys. Keys are compared using `equal'." (setcdr cell (push elt (cdr cell))) (push (list key elt) acc)) acc)) - (seq-reverse seq) + (seq-reverse sequence) nil)) -(cl-defgeneric seq-min (seq) - "Return the smallest element of SEQ. -SEQ must be a sequence of numbers or markers." - (apply #'min (seq-into seq 'list))) +(cl-defgeneric seq-min (sequence) + "Return the smallest element of SEQUENCE. +SEQUENCE must be a sequence of numbers or markers." + (apply #'min (seq-into sequence 'list))) -(cl-defgeneric seq-max (seq) - "Return the largest element of SEQ. -SEQ must be a sequence of numbers or markers." - (apply #'max (seq-into seq 'list))) +(cl-defgeneric seq-max (sequence) + "Return the largest element of SEQUENCE. +SEQUENCE must be a sequence of numbers or markers." + (apply #'max (seq-into sequence 'list))) -(defun seq--count-successive (pred seq) - "Return the number of successive elements for which (PRED element) is non-nil in SEQ." +(defun seq--count-successive (pred sequence) + "Return the number of successive elements for which (PRED element) is non-nil in SEQUENCE." (let ((n 0) - (len (seq-length seq))) + (len (seq-length sequence))) (while (and (< n len) - (funcall pred (seq-elt seq n))) + (funcall pred (seq-elt sequence n))) (setq n (+ 1 n))) n)) @@ -419,10 +424,10 @@ SEQ must be a sequence of numbers or markers." args))) ;; TODO: make public? -(defun seq--elt-safe (seq n) - "Return element of SEQ at the index N. +(defun seq--elt-safe (sequence n) + "Return element of SEQUENCE at the index N. If no element is found, return nil." - (ignore-errors (seq-elt seq n))) + (ignore-errors (seq-elt sequence n))) ;;; Optimized implementations for lists diff --git a/lisp/emacs-lisp/thunk.el b/lisp/emacs-lisp/thunk.el index d07b25736aa..0c5816a616d 100644 --- a/lisp/emacs-lisp/thunk.el +++ b/lisp/emacs-lisp/thunk.el @@ -57,8 +57,8 @@ ,forced (unless ,forced (setf ,val (progn ,@body)) - (setf ,forced t))) - ,val)))) + (setf ,forced t)) + ,val))))) (defun thunk-force (delayed) "Force the evaluation of DELAYED. diff --git a/lisp/filenotify.el b/lisp/filenotify.el index 55d9028f252..6a180a86570 100644 --- a/lisp/filenotify.el +++ b/lisp/filenotify.el @@ -48,32 +48,33 @@ The value in the hash table is a list Several values for a given DIR happen only for `inotify', when different files from the same directory are watched.") -(defun file-notify--rm-descriptor (descriptor) +(defun file-notify--rm-descriptor (descriptor &optional what) "Remove DESCRIPTOR from `file-notify-descriptors'. DESCRIPTOR should be an object returned by `file-notify-add-watch'. -If it is registered in `file-notify-descriptors', a stopped event is sent." +If it is registered in `file-notify-descriptors', a stopped event is sent. +WHAT is a file or directory name to be removed, needed just for `inotify'." (let* ((desc (if (consp descriptor) (car descriptor) descriptor)) (file (if (consp descriptor) (cdr descriptor))) (registered (gethash desc file-notify-descriptors)) (dir (car registered))) - (when (consp registered) + (when (and (consp registered) (or (null what) (string-equal dir what))) ;; Send `stopped' event. (dolist (entry (cdr registered)) - (funcall (cdr entry) - `(,(file-notify--descriptor desc) stopped - ,(or (and (stringp (car entry)) - (expand-file-name (car entry) dir)) - dir)))) + (funcall (cdr entry) + `(,(file-notify--descriptor desc) stopped + ,(or (and (stringp (car entry)) + (expand-file-name (car entry) dir)) + dir)))) ;; Modify `file-notify-descriptors'. (if (not file) - (remhash desc file-notify-descriptors) - (setcdr registered - (delete (assoc file (cdr registered)) (cdr registered))) - (if (null (cdr registered)) - (remhash desc file-notify-descriptors) - (puthash desc registered file-notify-descriptors)))))) + (remhash desc file-notify-descriptors) + (setcdr registered + (delete (assoc file (cdr registered)) (cdr registered))) + (if (null (cdr registered)) + (remhash desc file-notify-descriptors) + (puthash desc registered file-notify-descriptors)))))) ;; This function is used by `gfilenotify', `inotify' and `w32notify' events. ;;;###autoload @@ -85,6 +86,7 @@ If EVENT is a filewatch event, call its callback. It has the format Otherwise, signal a `file-notify-error'." (interactive "e") + ;;(message "file-notify-handle-event %S" event) (if (and (eq (car event) 'file-notify) (>= (length event) 3)) (funcall (nth 2 event) (nth 1 event)) @@ -224,6 +226,7 @@ EVENT is the cadr of the event in `file-notify-handle-event' (setq pending-event nil)) ;; Check for stopped. + ;;(message "file-notify-callback %S %S" file registered) (setq stopped (or @@ -232,7 +235,9 @@ EVENT is the cadr of the event in `file-notify-handle-event' (memq action '(deleted renamed)) (= (length (cdr registered)) 1) (string-equal - (or (file-name-nondirectory file) "") (car (cadr registered)))))) + (file-name-nondirectory file) + (or (file-name-nondirectory (car registered)) + (car (cadr registered))))))) ;; Apply callback. (when (and action @@ -257,7 +262,7 @@ EVENT is the cadr of the event in `file-notify-handle-event' ;; Modify `file-notify-descriptors'. (when stopped - (file-notify--rm-descriptor (file-notify--descriptor desc)))))) + (file-notify--rm-descriptor (file-notify--descriptor desc) file))))) ;; `gfilenotify' and `w32notify' return a unique descriptor for every ;; `file-notify-add-watch', while `inotify' returns a unique @@ -324,8 +329,8 @@ FILE is the name of the file whose event is being reported." (setq desc (funcall handler 'file-notify-add-watch dir flags callback)) - ;; Check, whether Emacs has been compiled with file - ;; notification support. + ;; Check, whether Emacs has been compiled with file notification + ;; support. (unless file-notify--library (signal 'file-notify-error '("No file notification package available"))) @@ -344,7 +349,8 @@ FILE is the name of the file whose event is being reported." (setq l-flags (cond - ((eq file-notify--library 'inotify) '(create modify move delete)) + ((eq file-notify--library 'inotify) + '(create delete delete-self modify move-self move)) ((eq file-notify--library 'w32notify) '(file-name directory-name size last-write-time))))) (when (memq 'attribute-change flags) diff --git a/lisp/gnus/gnus-topic.el b/lisp/gnus/gnus-topic.el index 7c6e1098100..b9897832517 100644 --- a/lisp/gnus/gnus-topic.el +++ b/lisp/gnus/gnus-topic.el @@ -508,7 +508,6 @@ articles in the topic and its subtopics." (all-entries entries) (point-max (point-max)) (unread 0) - (topic (car type)) info entry end active tick) ;; Insert any sub-topics. (while topicl @@ -586,7 +585,7 @@ articles in the topic and its subtopics." (goto-char end) unread)) -(defun gnus-topic-remove-topic (&optional insert total-remove hide in-level) +(defun gnus-topic-remove-topic (&optional insert total-remove _hide in-level) "Remove the current topic." (let ((topic (gnus-group-topic-name)) (level (gnus-group-topic-level)) @@ -631,6 +630,8 @@ articles in the topic and its subtopics." (or insert (not (gnus-topic-visible-p))) nil nil 9) (gnus-topic-enter-dribble))))))) +(defvar gnus-tmp-header) + (defun gnus-topic-insert-topic-line (name visiblep shownp level entries &optional unread) (let* ((visible (if visiblep "" "...")) @@ -694,8 +695,7 @@ articles in the topic and its subtopics." (let* ((topic (gnus-group-topic group)) (groups (cdr (assoc topic gnus-topic-alist))) (g (cdr (member group groups))) - (unfound t) - entry) + (unfound t)) ;; Try to jump to a visible group. (while (and g (not (gnus-group-goto-group (car g) t))) @@ -1454,7 +1454,7 @@ If NON-RECURSIVE (which is the prefix) is t, don't mark its subtopics." (funcall (if unmark 'gnus-group-remove-mark 'gnus-group-set-mark) (gnus-info-group (nth 2 (pop groups))))))))) -(defun gnus-topic-unmark-topic (topic &optional dummy non-recursive) +(defun gnus-topic-unmark-topic (topic &optional _dummy non-recursive) "Remove the process mark from all groups in the TOPIC. If NON-RECURSIVE (which is the prefix) is t, don't unmark its subtopics." (interactive (list (gnus-group-topic-name) @@ -1488,15 +1488,14 @@ If NON-RECURSIVE (which is the prefix) is t, don't unmark its subtopics." (gnus-group-mark-regexp regexp) (gnus-topic-move-group nil topic copyp)) -(defun gnus-topic-copy-matching (regexp topic &optional copyp) +(defun gnus-topic-copy-matching (regexp topic &optional _copyp) "Copy all groups that match REGEXP to some topic." (interactive - (let (topic) + (let ((topic (gnus-completing-read "Copy to topic" + (mapcar #'car gnus-topic-alist) t))) (nreverse - (list - (setq topic (gnus-completing-read "Copy to topic" - (mapcar 'car gnus-topic-alist) t)) - (read-string (format "Copy to %s (regexp): " topic)))))) + (list topic + (read-string (format "Copy to %s (regexp): " topic)))))) (gnus-topic-move-matching regexp topic t)) (defun gnus-topic-delete (topic) diff --git a/lisp/help.el b/lisp/help.el index 3387628fb8a..c558b652b7e 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -1394,9 +1394,10 @@ ARGLIST can also be t or a string of the form \"(FUN ARG1 ARG2 ...)\"." (if (string-match "\n?\n\\'" docstring) (if (< (- (match-end 0) (match-beginning 0)) 2) "\n" "") "\n\n") - (if (and (stringp arglist) - (string-match "\\`([^ ]+\\(.*\\))\\'" arglist)) - (concat "(fn" (match-string 1 arglist) ")") + (if (stringp arglist) + (if (string-match "\\`[^ ]+\\(.*\\))\\'" arglist) + (concat "(fn" (match-string 1 arglist) ")") + (error "Unrecognized usage format")) (help--make-usage-docstring 'fn arglist))))) (defun help-function-arglist (def &optional preserve-names) diff --git a/lisp/international/ccl.el b/lisp/international/ccl.el index daba2b6ed09..2fcbc884b35 100644 --- a/lisp/international/ccl.el +++ b/lisp/international/ccl.el @@ -1,4 +1,4 @@ -;;; ccl.el --- CCL (Code Conversion Language) compiler +;;; ccl.el --- CCL (Code Conversion Language) compiler -*- lexical-binding:t -*- ;; Copyright (C) 1997-1998, 2001-2015 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, @@ -479,8 +479,7 @@ If READ-FLAG is non-nil, this statement has the form (let ((condition (nth 1 cmd)) (true-cmds (nth 2 cmd)) (false-cmds (nth 3 cmd)) - jump-cond-address - false-ic) + jump-cond-address) (if (and (listp condition) (listp (car condition))) ;; If CONDITION is a nested expression, the inner expression @@ -678,8 +677,7 @@ is a list of CCL-BLOCKs." (ccl-embed-code 'write-const-jump 0 ccl-loop-head) (ccl-embed-data arg)) ((stringp arg) - (let ((len (length arg)) - (i 0)) + (let ((len (length arg))) (ccl-embed-code 'write-string-jump 0 ccl-loop-head) (ccl-embed-data len) (ccl-embed-string len arg))) @@ -920,8 +918,7 @@ is a list of CCL-BLOCKs." (error "CCL: Invalid number of arguments: %s" cmd)) (let ((RRR (nth 1 cmd)) (rrr (nth 2 cmd)) - (map (nth 3 cmd)) - id) + (map (nth 3 cmd))) (ccl-check-register rrr cmd) (ccl-check-register RRR cmd) (ccl-embed-extended-command 'map-single rrr RRR 0) @@ -962,10 +959,11 @@ is a list of CCL-BLOCKs." (defvar ccl-code) ;;;###autoload -(defun ccl-dump (ccl-code) - "Disassemble compiled CCL-CODE." - (let ((len (length ccl-code)) - (buffer-mag (aref ccl-code 0))) +(defun ccl-dump (code) + "Disassemble compiled CCL-code CODE." + (let* ((ccl-code code) + (len (length ccl-code)) + (buffer-mag (aref ccl-code 0))) (cond ((= buffer-mag 0) (insert (substitute-command-keys "Don't output anything.\n"))) ((= buffer-mag 1) @@ -1005,7 +1003,7 @@ is a list of CCL-BLOCKs." (defun ccl-dump-set-short-const (rrr cc) (insert (format "r%d = %d\n" rrr cc))) -(defun ccl-dump-set-const (rrr ignore) +(defun ccl-dump-set-const (rrr _ignore) (insert (format "r%d = %d\n" rrr (ccl-get-next-code)))) (defun ccl-dump-set-array (rrr cc) @@ -1019,7 +1017,7 @@ is a list of CCL-BLOCKs." (setq i (1+ i))) (insert "\n"))) -(defun ccl-dump-jump (ignore cc &optional address) +(defun ccl-dump-jump (_ignore cc &optional address) (insert (format "jump to %d(" (+ (or address ccl-current-ic) cc))) (if (>= cc 0) (insert "+")) @@ -1042,13 +1040,13 @@ is a list of CCL-BLOCKs." (defun ccl-extract-arith-op (cc) (aref ccl-arith-table (ash cc -6))) -(defun ccl-dump-write-expr-const (ignore cc) +(defun ccl-dump-write-expr-const (_ignore cc) (insert (format "write (r%d %s %d)\n" (logand cc 7) (ccl-extract-arith-op cc) (ccl-get-next-code)))) -(defun ccl-dump-write-expr-register (ignore cc) +(defun ccl-dump-write-expr-register (_ignore cc) (insert (format "write (r%d %s r%d)\n" (logand cc 7) (ccl-extract-arith-op cc) @@ -1059,7 +1057,7 @@ is a list of CCL-BLOCKs." ((= cc ?\n) (insert " \"^J\"")) (t (insert (format " \"%c\"" cc))))) -(defun ccl-dump-write-const-jump (ignore cc) +(defun ccl-dump-write-const-jump (_ignore cc) (let ((address ccl-current-ic)) (insert "write char") (ccl-dump-insert-char (ccl-get-next-code)) @@ -1075,7 +1073,7 @@ is a list of CCL-BLOCKs." (ccl-get-next-code) ; Skip dummy READ-JUMP )) -(defun ccl-dump-write-string-jump (ignore cc) +(defun ccl-dump-write-string-jump (_ignore cc) (let ((address ccl-current-ic) (len (ccl-get-next-code)) (i 0)) @@ -1125,7 +1123,7 @@ is a list of CCL-BLOCKs." (defun ccl-dump-write-register (rrr cc) (insert (format "write r%d (%d remaining)\n" rrr cc))) -(defun ccl-dump-call (ignore cc) +(defun ccl-dump-call (_ignore _cc) (let ((subroutine (car (ccl-get-next-code)))) (insert (format-message "call subroutine `%s'\n" subroutine)))) @@ -1160,7 +1158,7 @@ is a list of CCL-BLOCKs." (setq i (1+ i))) (insert "\n"))) -(defun ccl-dump-end (&rest ignore) +(defun ccl-dump-end (&rest _ignore) (insert "end\n")) (defun ccl-dump-set-assign-expr-const (rrr cc) @@ -1213,9 +1211,10 @@ is a list of CCL-BLOCKs." (insert (format "read r%d, " rrr)) (ccl-dump-jump-cond-expr-register rrr cc)) -(defun ccl-dump-binary (ccl-code) - (let ((len (length ccl-code)) - (i 2)) +(defun ccl-dump-binary (code) + (let* ((ccl-code code) + (len (length ccl-code)) + (i 2)) (while (< i len) (let ((code (aref ccl-code i)) (j 27)) @@ -1235,28 +1234,28 @@ is a list of CCL-BLOCKs." (insert (format "<%s> " ex-op)) (funcall (get ex-op 'ccl-dump-function) rrr RRR Rrr))) -(defun ccl-dump-read-multibyte-character (rrr RRR Rrr) +(defun ccl-dump-read-multibyte-character (rrr RRR _Rrr) (insert (format "read-multibyte-character r%d r%d\n" RRR rrr))) -(defun ccl-dump-write-multibyte-character (rrr RRR Rrr) +(defun ccl-dump-write-multibyte-character (rrr RRR _Rrr) (insert (format "write-multibyte-character r%d r%d\n" RRR rrr))) (defun ccl-dump-translate-character (rrr RRR Rrr) (insert (format "translation table(r%d) r%d r%d\n" Rrr RRR rrr))) -(defun ccl-dump-translate-character-const-tbl (rrr RRR Rrr) +(defun ccl-dump-translate-character-const-tbl (rrr RRR _Rrr) (let ((tbl (ccl-get-next-code))) (insert (format "translation table(%S) r%d r%d\n" tbl RRR rrr)))) -(defun ccl-dump-lookup-int-const-tbl (rrr RRR Rrr) +(defun ccl-dump-lookup-int-const-tbl (rrr RRR _Rrr) (let ((tbl (ccl-get-next-code))) (insert (format "hash table(%S) r%d r%d\n" tbl RRR rrr)))) -(defun ccl-dump-lookup-char-const-tbl (rrr RRR Rrr) +(defun ccl-dump-lookup-char-const-tbl (rrr RRR _Rrr) (let ((tbl (ccl-get-next-code))) (insert (format "hash table(%S) r%d r%d\n" tbl RRR rrr)))) -(defun ccl-dump-iterate-multiple-map (rrr RRR Rrr) +(defun ccl-dump-iterate-multiple-map (rrr RRR _Rrr) (let ((notbl (ccl-get-next-code)) (i 0) id) (insert (format "iterate-multiple-map r%d r%d\n" RRR rrr)) @@ -1267,7 +1266,7 @@ is a list of CCL-BLOCKs." (setq i (1+ i))) (insert "]\n"))) -(defun ccl-dump-map-multiple (rrr RRR Rrr) +(defun ccl-dump-map-multiple (rrr RRR _Rrr) (let ((notbl (ccl-get-next-code)) (i 0) id) (insert (format "map-multiple r%d r%d\n" RRR rrr)) @@ -1280,7 +1279,7 @@ is a list of CCL-BLOCKs." (setq i (1+ i))) (insert "]\n"))) -(defun ccl-dump-map-single (rrr RRR Rrr) +(defun ccl-dump-map-single (rrr RRR _Rrr) (let ((id (ccl-get-next-code))) (insert (format "map-single r%d r%d map(%S)\n" RRR rrr id)))) diff --git a/lisp/json.el b/lisp/json.el index e2c7cc77222..b23d12ad0ed 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -358,7 +358,7 @@ Please see the documentation of `json-object-type'." (cond ((eq json-object-type 'hash-table) (make-hash-table :test 'equal)) (t - (list)))) + ()))) (defun json-add-to-object (object key value) "Add a new KEY -> VALUE association to OBJECT. diff --git a/lisp/net/eww.el b/lisp/net/eww.el index 6a315496fe0..5748e88bbca 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -1501,7 +1501,7 @@ If CHARSET is nil then use UTF-8." (setq start (point) title (plist-get bookmark :title)) (when (> (length title) width) - (setq title (substring title 0 width))) + (setq title (truncate-string-to-width title width))) (insert (format format title (plist-get bookmark :url)) "\n") (put-text-property start (1+ start) 'eww-bookmark bookmark)) (goto-char (point-min)))) diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 5910d1fd3a4..c0a6b6afa6d 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -649,8 +649,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (directory &optional full match nosort) "Like `directory-files' for Tramp files." (let ((result (mapcar 'directory-file-name - (file-name-all-completions "" directory))) - res) + (file-name-all-completions "" directory)))) ;; Discriminate with regexp. (when match (setq result @@ -665,9 +664,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." result))) ;; Sort them if necessary. (unless nosort (setq result (sort result 'string-lessp))) - ;; Remove double entries. - (dolist (elt result res) - (add-to-list 'res elt 'append)))) + (delete-dups result))) (defun tramp-smb-handle-expand-file-name (name &optional dir) "Like `expand-file-name' for Tramp files." diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 30a7269240e..2f811bb73ca 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -4043,6 +4043,7 @@ Return the local name of the temporary file." 'tramp-delete-temp-file-function))) ;;; Auto saving to a special directory: +(defvar auto-save-file-name-transforms) (defun tramp-handle-make-auto-save-file-name () "Like `make-auto-save-file-name' for Tramp files. diff --git a/lisp/obsolete/vc-arch.el b/lisp/obsolete/vc-arch.el index bdb69757d35..e6540ce74d9 100644 --- a/lisp/obsolete/vc-arch.el +++ b/lisp/obsolete/vc-arch.el @@ -310,6 +310,10 @@ Only the value `maybe' can be trusted :-(." 'up-to-date 'edited))))))))) +;; dir-status-files called from vc-dir, which loads vc, +;; which loads vc-dispatcher. +(declare-function vc-exec-after "vc-dispatcher" (code)) + (defun vc-arch-dir-status-files (dir _files callback) "Run `tla inventory' for DIR and pass results to CALLBACK. CALLBACK expects (ENTRIES &optional MORE-TO-COME); see diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index 45afafc2381..0b13759b9bc 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el @@ -3410,18 +3410,24 @@ There might be text before point." "A `prettify-symbols-alist' usable for (La)TeX modes.") (defun tex--prettify-symbols-compose-p (_start end _match) - (let* ((after-char (char-after end)) - (after-syntax (char-syntax after-char))) - (not (or - ;; Don't compose \alpha@foo. - (eq after-char ?@) - ;; The \alpha in \alpha2 or \alpha-\beta may be composed but - ;; of course \alphax may not. - (and (eq after-syntax ?w) - (not (memq after-char - '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?+ ?- ?' ?\")))) - ;; Don't compose inside verbatim blocks. - (eq 2 (nth 7 (syntax-ppss))))))) + (or + ;; If the matched symbol doesn't end in a word character, then we + ;; simply allow composition. The symbol is probably something like + ;; \|, \(, etc. + (not (eq ?w (char-syntax (char-before end)))) + ;; Else we look at what follows the match in order to decide. + (let* ((after-char (char-after end)) + (after-syntax (char-syntax after-char))) + (not (or + ;; Don't compose \alpha@foo. + (eq after-char ?@) + ;; The \alpha in \alpha2 or \alpha-\beta may be composed but + ;; of course \alphax may not. + (and (eq after-syntax ?w) + (not (memq after-char + '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?+ ?- ?' ?\")))) + ;; Don't compose inside verbatim blocks. + (eq 2 (nth 7 (syntax-ppss)))))))) (run-hooks 'tex-mode-load-hook) diff --git a/lisp/vc/vc-bzr.el b/lisp/vc/vc-bzr.el index 40f251654f2..9b2711d8146 100644 --- a/lisp/vc/vc-bzr.el +++ b/lisp/vc/vc-bzr.el @@ -331,6 +331,7 @@ in the repository root directory of FILE." "Value of `compilation-error-regexp-alist' in *vc-bzr* buffers.") ;; To be called via vc-pull from vc.el, which requires vc-dispatcher. +(declare-function vc-exec-after "vc-dispatcher" (code)) (declare-function vc-set-async-update "vc-dispatcher" (process-buffer)) (declare-function vc-compilation-mode "vc-dispatcher" (backend)) diff --git a/lisp/vc/vc-cvs.el b/lisp/vc/vc-cvs.el index c0a199dc078..5f5807fb3c6 100644 --- a/lisp/vc/vc-cvs.el +++ b/lisp/vc/vc-cvs.el @@ -543,6 +543,8 @@ Will fail unless you have administrative privileges on the repo." ;;; (declare-function vc-rcs-print-log-cleanup "vc-rcs" ()) +;; Follows vc-cvs-command, which uses vc-do-command from vc-dispatcher. +(declare-function vc-exec-after "vc-dispatcher" (code)) (defun vc-cvs-print-log (files buffer &optional _shortlog _start-revision limit) "Print commit log associated with FILES into specified BUFFER. diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index 0e33896a715..27898a991a0 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -461,6 +461,8 @@ or an empty string if none." ;; Follows vc-git-command (or vc-do-async-command), which uses vc-do-command ;; from vc-dispatcher. +(declare-function vc-exec-after "vc-dispatcher" (code)) +;; Follows vc-exec-after. (declare-function vc-set-async-update "vc-dispatcher" (process-buffer)) (defun vc-git-dir-status-goto-stage (stage files update-function) diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index c4d6092d100..f9957c1afff 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -259,6 +259,14 @@ highlighting the Log View buffer." (defvar vc-hg-log-graph nil "If non-nil, use `--graph' in the short log output.") +(defvar vc-hg-log-format (concat "changeset: {rev}:{node|short}\n" + "{tags % 'tag: {tag}\n'}" + "{if(parents, 'parents: {parents}\n')}" + "user: {author}\n" + "Date: {date|date}\n" + "summary: {desc|tabindent}\n\n") + "Mercurial log template for `vc-hg-print-log' long format.") + (defun vc-hg-print-log (files buffer &optional shortlog start-revision limit) "Print commit log associated with FILES into specified BUFFER. If SHORTLOG is non-nil, use a short format based on `vc-hg-root-log-format'. @@ -276,9 +284,11 @@ If LIMIT is non-nil, show no more than this many entries." (nconc (when start-revision (list (format "-r%s:0" start-revision))) (when limit (list "-l" (format "%s" limit))) - (when shortlog `(,@(if vc-hg-log-graph '("--graph")) - "--template" - ,(car vc-hg-root-log-format))) + (if shortlog + `(,@(if vc-hg-log-graph '("--graph")) + "--template" + ,(car vc-hg-root-log-format)) + `("--template" ,vc-hg-log-format)) vc-hg-log-switches))))) (defvar log-view-message-re) @@ -295,6 +305,7 @@ If LIMIT is non-nil, show no more than this many entries." (if (eq vc-log-view-type 'short) (cadr vc-hg-root-log-format) "^changeset:[ \t]*\\([0-9]+\\):\\(.+\\)")) + (set (make-local-variable 'tab-width) 2) ;; Allow expanding short log entries (when (eq vc-log-view-type 'short) (setq truncate-lines t) @@ -345,7 +356,7 @@ If LIMIT is non-nil, show no more than this many entries." (defun vc-hg-expanded-log-entry (revision) (with-temp-buffer - (vc-hg-command t nil nil "log" "-r" revision) + (vc-hg-command t nil nil "log" "-r" revision "--template" vc-hg-log-format) (goto-char (point-min)) (unless (eobp) ;; Indent the expanded log entry. @@ -620,6 +631,8 @@ REV is the revision to check out into WORKFILE." ;; Follows vc-hg-command (or vc-do-async-command), which uses vc-do-command ;; from vc-dispatcher. +(declare-function vc-exec-after "vc-dispatcher" (code)) +;; Follows vc-exec-after. (declare-function vc-set-async-update "vc-dispatcher" (process-buffer)) (defun vc-hg-dir-status-files (dir files update-function) diff --git a/lisp/vc/vc-mtn.el b/lisp/vc/vc-mtn.el index 3197d606061..b56a08f2a9e 100644 --- a/lisp/vc/vc-mtn.el +++ b/lisp/vc/vc-mtn.el @@ -138,6 +138,10 @@ switches." ((match-end 2) (push (list (match-string 3) 'added) result)))) (funcall update-function result))) +;; dir-status-files called from vc-dir, which loads vc, +;; which loads vc-dispatcher. +(declare-function vc-exec-after "vc-dispatcher" (code)) + (defun vc-mtn-dir-status-files (dir _files update-function) (vc-mtn-command (current-buffer) 'async dir "status") (vc-run-delayed diff --git a/lisp/vc/vc-svn.el b/lisp/vc/vc-svn.el index 2ec65a1ad07..4ef63a23db5 100644 --- a/lisp/vc/vc-svn.el +++ b/lisp/vc/vc-svn.el @@ -208,6 +208,10 @@ switches." (setq result (cons (list filename state) result))))) (funcall callback result))) +;; dir-status-files called from vc-dir, which loads vc, +;; which loads vc-dispatcher. +(declare-function vc-exec-after "vc-dispatcher" (code)) + (autoload 'vc-expand-dirs "vc") (defun vc-svn-dir-status-files (_dir files callback) diff --git a/src/lread.c b/src/lread.c index a98fa6199f1..1119f3fdfd4 100644 --- a/src/lread.c +++ b/src/lread.c @@ -4479,8 +4479,10 @@ were read in. */); DEFVAR_LISP ("load-path", Vload_path, doc: /* List of directories to search for files to load. -Each element is a string (directory name) or nil (meaning `default-directory'). -Initialized during startup as described in Info node `(elisp)Library Search'. */); +Each element is a string (directory file name) or nil (meaning +`default-directory'). Initialized during startup as described in Info +node `(elisp)Library Search'. Use `directory-file-name' when adding items +to this path. */); DEFVAR_LISP ("load-suffixes", Vload_suffixes, doc: /* List of suffixes for (compiled or source) Emacs Lisp files. diff --git a/src/nsfns.m b/src/nsfns.m index 1ed3e23cba5..c24344436ad 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -1298,6 +1298,8 @@ This function is an internal primitive--use `make-frame' instead. */) = [NSCursor arrowCursor]; f->output_data.ns->current_pointer = f->output_data.ns->text_cursor; + f->output_data.ns->in_animation = NO; + [[EmacsView alloc] initFrameFromEmacs: f]; x_icon (f, parms); diff --git a/src/nsmenu.m b/src/nsmenu.m index 2ef12234960..ddc5dc20a82 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -998,10 +998,20 @@ free_frame_tool_bar (struct frame *f) -------------------------------------------------------------------------- */ { EmacsView *view = FRAME_NS_VIEW (f); + + NSTRACE ("free_frame_tool_bar"); + block_input (); view->wait_for_tool_bar = NO; - [[view toolbar] setVisible: NO]; + FRAME_TOOLBAR_HEIGHT (f) = 0; + + /* Note: This trigger an animation, which calls windowDidResize + repeatedly. */ + f->output_data.ns->in_animation = 1; + [[view toolbar] setVisible: NO]; + f->output_data.ns->in_animation = 0; + unblock_input (); } @@ -1017,6 +1027,8 @@ update_frame_tool_bar (struct frame *f) EmacsToolbar *toolbar = [view toolbar]; int oldh; + NSTRACE ("update_frame_tool_bar"); + if (view == nil || toolbar == nil) return; block_input (); @@ -1096,7 +1108,11 @@ update_frame_tool_bar (struct frame *f) } if (![toolbar isVisible]) + { + f->output_data.ns->in_animation = 1; [toolbar setVisible: YES]; + f->output_data.ns->in_animation = 0; + } #ifdef NS_IMPL_COCOA if ([toolbar changed]) @@ -1150,6 +1166,8 @@ update_frame_tool_bar (struct frame *f) - initForView: (EmacsView *)view withIdentifier: (NSString *)identifier { + NSTRACE ("[EmacsToolbar initForView: withIdentifier:]"); + self = [super initWithIdentifier: identifier]; emacsView = view; [self setDisplayMode: NSToolbarDisplayModeIconOnly]; @@ -1164,6 +1182,8 @@ update_frame_tool_bar (struct frame *f) - (void)dealloc { + NSTRACE ("[EmacsToolbar dealloc]"); + [prevIdentifiers release]; [activeIdentifiers release]; [identifierToItem release]; @@ -1172,6 +1192,8 @@ update_frame_tool_bar (struct frame *f) - (void) clearActive { + NSTRACE ("[EmacsToolbar clearActive]"); + [prevIdentifiers release]; prevIdentifiers = [activeIdentifiers copy]; [activeIdentifiers removeAllObjects]; @@ -1181,6 +1203,8 @@ update_frame_tool_bar (struct frame *f) - (void) clearAll { + NSTRACE ("[EmacsToolbar clearAll]"); + [self clearActive]; while ([[self items] count] > 0) [self removeItemAtIndex: 0]; @@ -1188,6 +1212,8 @@ update_frame_tool_bar (struct frame *f) - (BOOL) changed { + NSTRACE ("[EmacsToolbar changed]"); + return [activeIdentifiers isEqualToArray: prevIdentifiers] && enablement == prevEnablement ? NO : YES; } @@ -1198,6 +1224,8 @@ update_frame_tool_bar (struct frame *f) helpText: (const char *)help enabled: (BOOL)enabled { + NSTRACE ("[EmacsToolbar addDisplayItemWithImage: ...]"); + /* 1) come up w/identifier */ NSString *identifier = [NSString stringWithFormat: @"%lu", (unsigned long)[img hash]]; @@ -1231,6 +1259,7 @@ update_frame_tool_bar (struct frame *f) all items to enabled state (for some reason). */ - (void)validateVisibleItems { + NSTRACE ("[EmacsToolbar validateVisibleItems]"); } @@ -1240,12 +1269,16 @@ update_frame_tool_bar (struct frame *f) itemForItemIdentifier: (NSString *)itemIdentifier willBeInsertedIntoToolbar: (BOOL)flag { + NSTRACE ("[EmacsToolbar toolbar: ...]"); + /* look up NSToolbarItem by identifier and return... */ return [identifierToItem objectForKey: itemIdentifier]; } - (NSArray *)toolbarDefaultItemIdentifiers: (NSToolbar *)toolbar { + NSTRACE ("[EmacsToolbar toolbarDefaultItemIdentifiers:]"); + /* return entire set.. */ return activeIdentifiers; } @@ -1253,6 +1286,8 @@ update_frame_tool_bar (struct frame *f) /* for configuration palette (not yet supported) */ - (NSArray *)toolbarAllowedItemIdentifiers: (NSToolbar *)toolbar { + NSTRACE ("[EmacsToolbar toolbarAllowedItemIdentifiers:]"); + /* return entire set... */ return activeIdentifiers; //return [identifierToItem allKeys]; diff --git a/src/nsterm.h b/src/nsterm.h index 8d52dc642ed..3fb8cfc9cd8 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -65,9 +65,12 @@ typedef float EmacsCGFloat; ========================================================================== */ -/* Uncomment the following line to enable trace. */ +/* Uncomment the following line to enable trace. -/* #define NSTRACE_ENABLED 1 */ + Hint: keep the trailing whitespace -- the version control system + will reject accidental commits. */ + +/* #define NSTRACE_ENABLED 1 */ /* Print a call tree containing all annotated functions. @@ -913,6 +916,9 @@ struct ns_output /* Non-zero if we are zooming (maximizing) the frame. */ int zooming; + + /* Non-zero if we are doing an animation, e.g. toggling the tool bar. */ + int in_animation; }; /* this dummy decl needed to support TTYs */ diff --git a/src/nsterm.m b/src/nsterm.m index be860610b47..925e9af30a7 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -1501,7 +1501,7 @@ x_set_window_size (struct frame *f, if (view == nil) return; - NSTRACE_RECT ("input", wr); + NSTRACE_RECT ("current", wr); /*fprintf (stderr, "\tsetWindowSize: %d x %d, pixelwise %d, font size %d x %d\n", width, height, pixelwise, FRAME_COLUMN_WIDTH (f), FRAME_LINE_HEIGHT (f));*/ @@ -1563,7 +1563,6 @@ x_set_window_size (struct frame *f, make_number (FRAME_NS_TITLEBAR_HEIGHT (f)), make_number (FRAME_TOOLBAR_HEIGHT (f)))); - [view setRows: rows andColumns: cols]; NSTRACE_RECT ("setFrame", wr); [window setFrame: wr display: YES]; @@ -6171,6 +6170,8 @@ not_in_argv (NSString *arg) NSTRACE ("updateFrameSize"); NSTRACE_SIZE ("Original size", NSMakeSize (oldw, oldh)); NSTRACE_RECT ("Original frame", wr); + NSTRACE_MSG ("Original columns: %d", cols); + NSTRACE_MSG ("Original rows: %d", rows); if (! [self isFullscreen]) { @@ -6187,13 +6188,19 @@ not_in_argv (NSString *arg) if (wait_for_tool_bar) { if (FRAME_TOOLBAR_HEIGHT (emacsframe) == 0) - return; + { + NSTRACE_MSG ("Waiting for toolbar"); + return; + } wait_for_tool_bar = NO; } neww = (int)wr.size.width - emacsframe->border_width; newh = (int)wr.size.height - extra; + NSTRACE_SIZE ("New size", NSMakeSize (neww, newh)); + NSTRACE_MSG ("tool_bar_height: %d", emacsframe->tool_bar_height); + cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, neww); rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, newh); @@ -6203,6 +6210,9 @@ not_in_argv (NSString *arg) if (rows < MINHEIGHT) rows = MINHEIGHT; + NSTRACE_MSG ("New columns: %d", cols); + NSTRACE_MSG ("New rows: %d", rows); + if (oldr != rows || oldc != cols || neww != oldw || newh != oldh) { NSView *view = FRAME_NS_VIEW (emacsframe); @@ -6220,6 +6230,10 @@ not_in_argv (NSString *arg) [view setFrame: wr]; [self windowDidMove:nil]; // Update top/left. } + else + { + NSTRACE_MSG ("No change"); + } } - (NSSize)windowWillResize: (NSWindow *)sender toSize: (NSSize)frameSize @@ -6328,6 +6342,12 @@ not_in_argv (NSString *arg) { NSTRACE ("windowDidResize"); + if (emacsframe->output_data.ns->in_animation) + { + NSTRACE_MSG ("Ignored (in animation)"); + return; + } + if (! [self fsIsNative]) { NSWindow *theWindow = [notification object]; @@ -7425,6 +7445,7 @@ not_in_argv (NSString *arg) - (void) setRows: (int) r andColumns: (int) c { + NSTRACE ("[EmacsView setRows:%d andColumns:%d]", r, c); rows = r; cols = c; } diff --git a/src/process.c b/src/process.c index dc93b86cee2..ed1d59d01b0 100644 --- a/src/process.c +++ b/src/process.c @@ -7176,8 +7176,10 @@ setup_process_coding_systems (Lisp_Object process) } DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0, - doc: /* Return the (or a) process associated with BUFFER. -BUFFER may be a buffer or the name of one. */) + doc: /* Return the (or a) live process associated with BUFFER. +BUFFER may be a buffer or the name of one. +Return nil if all processes associated with BUFFER have been +deleted or killed. */) (register Lisp_Object buffer) { #ifdef subprocesses diff --git a/test/automated/auto-revert-tests.el b/test/automated/auto-revert-tests.el index 86184d613fc..7cabc5c3e66 100644 --- a/test/automated/auto-revert-tests.el +++ b/test/automated/auto-revert-tests.el @@ -136,8 +136,6 @@ buf) (unwind-protect (progn - (with-current-buffer (get-buffer-create "*Messages*") - (narrow-to-region (point-max) (point-max))) (setq buf (dired-noselect temporary-file-directory)) (with-current-buffer buf ;; `buffer-stale--default-function' checks for @@ -151,6 +149,8 @@ ;; Delete file. We wait for a second, in order to have ;; another timestamp. + (with-current-buffer (get-buffer-create "*Messages*") + (narrow-to-region (point-max) (point-max))) (sleep-for 1) (delete-file tmpfile) diff --git a/test/automated/file-notify-tests.el b/test/automated/file-notify-tests.el index 56b4f69597d..222bdc52928 100644 --- a/test/automated/file-notify-tests.el +++ b/test/automated/file-notify-tests.el @@ -61,6 +61,8 @@ (defvar file-notify--test-results nil) (defvar file-notify--test-event nil) (defvar file-notify--test-events nil) +(defvar file-notify--test-expected-events nil) + (defun file-notify--test-timeout () "Timeout to wait for arriving events, in seconds." (if (file-remote-p temporary-file-directory) 6 3)) @@ -71,12 +73,12 @@ (when (and file-notify--test-tmpfile (file-exists-p file-notify--test-tmpfile)) - (if (directory-name-p file-notify--test-tmpfile) + (if (file-directory-p file-notify--test-tmpfile) (delete-directory file-notify--test-tmpfile 'recursive) (delete-file file-notify--test-tmpfile))) (when (and file-notify--test-tmpfile1 (file-exists-p file-notify--test-tmpfile1)) - (if (directory-name-p file-notify--test-tmpfile1) + (if (file-directory-p file-notify--test-tmpfile1) (delete-directory file-notify--test-tmpfile1 'recursive) (delete-file file-notify--test-tmpfile1))) (when (file-remote-p temporary-file-directory) @@ -87,7 +89,8 @@ file-notify--test-tmpfile1 nil file-notify--test-desc nil file-notify--test-results nil - file-notify--test-events nil) + file-notify--test-events nil + file-notify--test-expected-events nil) (when file-notify--test-event (error "file-notify--test-event should not be set but bound dynamically"))) @@ -226,13 +229,16 @@ being the result.") "Ert test function to be called by `file-notify--test-event-handler'. We cannot pass arguments, so we assume that `file-notify--test-event' is bound somewhere." - ;;(message "Event %S" file-notify--test-event) ;; Check the descriptor. (should (equal (car file-notify--test-event) file-notify--test-desc)) ;; Check the file name. (should - (string-equal (file-notify--event-file-name file-notify--test-event) - file-notify--test-tmpfile)) + (or (string-equal (file-notify--event-file-name file-notify--test-event) + file-notify--test-tmpfile) + (string-equal (directory-file-name + (file-name-directory + (file-notify--event-file-name file-notify--test-event))) + file-notify--test-tmpfile))) ;; Check the second file name if exists. (when (eq (nth 1 file-notify--test-event) 'renamed) (should @@ -247,10 +253,15 @@ and the event to `file-notify--test-events'." (let* ((file-notify--test-event event) (result (ert-run-test (make-ert-test :body 'file-notify--test-event-test)))) - (setq file-notify--test-events - (append file-notify--test-events `(,file-notify--test-event)) - file-notify--test-results - (append file-notify--test-results `(,result))))) + ;; Do not add temporary files, this would confuse the checks. + (unless (string-match + (regexp-quote ".#") + (file-notify--event-file-name file-notify--test-event)) + ;;(message "file-notify--test-event-handler %S" file-notify--test-event) + (setq file-notify--test-events + (append file-notify--test-events `(,file-notify--test-event)) + file-notify--test-results + (append file-notify--test-results `(,result)))))) (defun file-notify--test-make-temp-name () "Create a temporary file name for test." @@ -270,6 +281,8 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." (declare (indent 2)) (let ((outer (make-symbol "outer"))) `(let ((,outer file-notify--test-events)) + (setq file-notify--test-expected-events + (append file-notify--test-expected-events ,events)) (let (file-notify--test-events) ,@body (file-notify--wait-for-events @@ -281,21 +294,47 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." (ert-deftest file-notify-test02-events () "Check file creation/change/removal notifications." (skip-unless (file-notify--test-local-enabled)) + + (setq file-notify--test-tmpfile (file-notify--test-make-temp-name) + file-notify--test-tmpfile1 (file-notify--test-make-temp-name)) + (unwind-protect (progn - ;; Check creation, change, and deletion. - (setq file-notify--test-tmpfile (file-notify--test-make-temp-name) - file-notify--test-tmpfile1 (file-notify--test-make-temp-name) - file-notify--test-desc + ;; Check creation, change and deletion. + (setq file-notify--test-desc (file-notify-add-watch file-notify--test-tmpfile '(change) 'file-notify--test-event-handler)) (file-notify--test-with-events - (file-notify--test-timeout) '(created changed deleted stopped) + (file-notify--test-timeout) '(created changed deleted) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) (delete-file file-notify--test-tmpfile)) - (file-notify-rm-watch file-notify--test-desc) + ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. + (let (file-notify--test-events) + (file-notify-rm-watch file-notify--test-desc)) + + ;; Check creation, change and deletion. There must be a + ;; `stopped' event when deleting the directory. It doesn't + ;; work for w32notify. + (unless (eq file-notify--library 'w32notify) + (make-directory file-notify--test-tmpfile) + (setq file-notify--test-desc + (file-notify-add-watch + file-notify--test-tmpfile + '(change) 'file-notify--test-event-handler)) + (file-notify--test-with-events + (file-notify--test-timeout) + ;; There are two `deleted' events, for the file and for + ;; the directory. + '(created changed deleted deleted stopped) + (write-region + "any text" nil (expand-file-name "foo" file-notify--test-tmpfile) + nil 'no-message) + (delete-directory file-notify--test-tmpfile 'recursive)) + ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. + (let (file-notify--test-events) + (file-notify-rm-watch file-notify--test-desc))) ;; Check copy. (setq file-notify--test-desc @@ -308,8 +347,8 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." ;; w32notify does not distinguish between `changed' and ;; `attribute-changed'. (if (eq file-notify--library 'w32notify) - '(created changed changed deleted stopped) - '(created changed deleted stopped)) + '(created changed changed deleted) + '(created changed deleted)) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) (copy-file file-notify--test-tmpfile file-notify--test-tmpfile1) @@ -319,7 +358,9 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." (set-file-times file-notify--test-tmpfile '(0 0)) (delete-file file-notify--test-tmpfile) (delete-file file-notify--test-tmpfile1)) - (file-notify-rm-watch file-notify--test-desc) + ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. + (let (file-notify--test-events) + (file-notify-rm-watch file-notify--test-desc)) ;; Check rename. (setq file-notify--test-desc @@ -328,13 +369,15 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." '(change) 'file-notify--test-event-handler)) (should file-notify--test-desc) (file-notify--test-with-events - (file-notify--test-timeout) '(created changed renamed stopped) + (file-notify--test-timeout) '(created changed renamed) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) (rename-file file-notify--test-tmpfile file-notify--test-tmpfile1) ;; After the rename, we won't get events anymore. (delete-file file-notify--test-tmpfile1)) - (file-notify-rm-watch file-notify--test-desc) + ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. + (let (file-notify--test-events) + (file-notify-rm-watch file-notify--test-desc)) ;; Check attribute change. It doesn't work for w32notify. (unless (eq file-notify--library 'w32notify) @@ -359,29 +402,16 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." (set-file-times file-notify--test-tmpfile '(0 0)) (read-event nil nil 0.1) (delete-file file-notify--test-tmpfile)) - (file-notify-rm-watch file-notify--test-desc)) + ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. + (let (file-notify--test-events) + (file-notify-rm-watch file-notify--test-desc))) ;; Check the global sequence again just to make sure that ;; `file-notify--test-events' has been set correctly. - (should (equal - (mapcar #'cadr file-notify--test-events) - (if (eq file-notify--library 'w32notify) - '(created changed deleted stopped - created changed changed deleted stopped - created changed renamed stopped) - (if (file-remote-p temporary-file-directory) - '(created changed deleted stopped - created changed deleted stopped - created changed renamed stopped - attribute-changed attribute-changed - attribute-changed stopped) - '(created changed deleted stopped - created changed deleted stopped - created changed renamed stopped - attribute-changed attribute-changed stopped))))) + (should (equal (mapcar #'cadr file-notify--test-events) + file-notify--test-expected-events)) (should file-notify--test-results) (dolist (result file-notify--test-results) - ;;(message "%s" (ert-test-result-messages result)) (when (ert-test-failed-p result) (ert-fail (cadr (ert-test-result-with-condition-condition result)))))) @@ -429,8 +459,10 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." (should auto-revert-use-notify) (should auto-revert-notify-watch-descriptor) - ;; Modify file. We wait for a second, in order to - ;; have another timestamp. + ;; Modify file. We wait for a second, in order to have + ;; another timestamp. + (with-current-buffer (get-buffer-create "*Messages*") + (narrow-to-region (point-max) (point-max))) (sleep-for 1) (write-region "another text" nil file-notify--test-tmpfile nil 'no-message) @@ -442,9 +474,34 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." (string-match (format-message "Reverting buffer `%s'." (buffer-name buf)) (buffer-string)))) - (should (string-match "another text" (buffer-string))))) + (should (string-match "another text" (buffer-string))) + + ;; Stop file notification. Autorevert shall still work via polling. + (file-notify-rm-watch auto-revert-notify-watch-descriptor) + (file-notify--wait-for-events + timeout (null auto-revert-use-notify)) + (should-not auto-revert-use-notify) + (should-not auto-revert-notify-watch-descriptor) + + ;; Modify file. We wait for two seconds, in order to have + ;; another timestamp. One second seems to be too short. + (with-current-buffer (get-buffer-create "*Messages*") + (narrow-to-region (point-max) (point-max))) + (sleep-for 2) + (write-region + "foo bla" nil file-notify--test-tmpfile nil 'no-message) + + ;; Check, that the buffer has been reverted. + (with-current-buffer (get-buffer-create "*Messages*") + (file-notify--wait-for-events + timeout + (string-match + (format-message "Reverting buffer `%s'." (buffer-name buf)) + (buffer-string)))) + (should (string-match "foo bla" (buffer-string))))) ;; Cleanup. + (with-current-buffer "*Messages*" (widen)) (ignore-errors (kill-buffer buf)) (file-notify--test-cleanup)))) @@ -463,41 +520,16 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." file-notify--test-tmpfile '(change) #'file-notify--test-event-handler)) (file-notify--test-with-events - (file-notify--test-timeout) '(created changed) + (file-notify--test-timeout) '(created changed deleted) (should (file-notify-valid-p file-notify--test-desc)) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) - (should (file-notify-valid-p file-notify--test-desc))) - ;; After removing the watch, the descriptor must not be valid + (delete-file file-notify--test-tmpfile)) + ;; After deleting the file, the descriptor is still valid. + (should (file-notify-valid-p file-notify--test-desc)) + ;; After removing the watch, the descriptor must not be valid ;; anymore. (file-notify-rm-watch file-notify--test-desc) - (file-notify--wait-for-events - (file-notify--test-timeout) - (not (file-notify-valid-p file-notify--test-desc))) - (should-not (file-notify-valid-p file-notify--test-desc))) - - ;; Cleanup. - (file-notify--test-cleanup)) - - (unwind-protect - (progn - (setq file-notify--test-tmpfile (file-notify--test-make-temp-name) - file-notify--test-desc - (file-notify-add-watch - file-notify--test-tmpfile - '(change) #'file-notify--test-event-handler)) - (file-notify--test-with-events - (file-notify--test-timeout) '(created changed) - (should (file-notify-valid-p file-notify--test-desc)) - (write-region - "any text" nil file-notify--test-tmpfile nil 'no-message) - (should (file-notify-valid-p file-notify--test-desc))) - ;; After deleting the file, the descriptor must not be valid - ;; anymore. - (delete-file file-notify--test-tmpfile) - (file-notify--wait-for-events - (file-notify--test-timeout) - (not (file-notify-valid-p file-notify--test-desc))) (should-not (file-notify-valid-p file-notify--test-desc))) ;; Cleanup. @@ -506,26 +538,23 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." (unwind-protect ;; The batch-mode operation of w32notify is fragile (there's no ;; input threads to send the message to). - (unless (and noninteractive (eq file-notify--library 'w32notify)) - (let ((temporary-file-directory (make-temp-file - "file-notify-test-parent" t))) + ;(unless (and noninteractive (eq file-notify--library 'w32notify)) + (unless (eq file-notify--library 'w32notify) + (let ((temporary-file-directory + (make-temp-file "file-notify-test-parent" t))) (setq file-notify--test-tmpfile (file-notify--test-make-temp-name) file-notify--test-desc (file-notify-add-watch file-notify--test-tmpfile '(change) #'file-notify--test-event-handler)) (file-notify--test-with-events - (file-notify--test-timeout) '(created changed) + (file-notify--test-timeout) '(created changed deleted stopped) (should (file-notify-valid-p file-notify--test-desc)) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) - (should (file-notify-valid-p file-notify--test-desc))) - ;; After deleting the parent, the descriptor must not be - ;; valid anymore. - (delete-directory temporary-file-directory t) - (file-notify--wait-for-events - (file-notify--test-timeout) - (not (file-notify-valid-p file-notify--test-desc))) + (delete-directory temporary-file-directory t)) + ;; After deleting the parent directory, the descriptor must + ;; not be valid anymore. (should-not (file-notify-valid-p file-notify--test-desc)))) ;; Cleanup. @@ -540,8 +569,8 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." (unwind-protect (progn - (setq file-notify--test-tmpfile (file-name-as-directory - (file-notify--test-make-temp-name))) + (setq file-notify--test-tmpfile + (file-name-as-directory (file-notify--test-make-temp-name))) (make-directory file-notify--test-tmpfile) (setq file-notify--test-desc (file-notify-add-watch @@ -551,6 +580,9 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." ;; After removing the watch, the descriptor must not be valid ;; anymore. (file-notify-rm-watch file-notify--test-desc) + (file-notify--wait-for-events + (file-notify--test-timeout) + (not (file-notify-valid-p file-notify--test-desc))) (should-not (file-notify-valid-p file-notify--test-desc))) ;; Cleanup. @@ -560,8 +592,8 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." ;; The batch-mode operation of w32notify is fragile (there's no ;; input threads to send the message to). (unless (and noninteractive (eq file-notify--library 'w32notify)) - (setq file-notify--test-tmpfile (file-name-as-directory - (file-notify--test-make-temp-name))) + (setq file-notify--test-tmpfile + (file-name-as-directory (file-notify--test-make-temp-name))) (make-directory file-notify--test-tmpfile) (setq file-notify--test-desc (file-notify-add-watch @@ -589,5 +621,10 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." (ert-run-tests-interactively "^file-notify-") (ert-run-tests-batch "^file-notify-"))) +;; TODO: + +;; * It does not work yet for local gfilenotify and remote inotifywait. +;; * For w32notify, no stopped events arrive when a directory is removed. + (provide 'file-notify-tests) ;;; file-notify-tests.el ends here diff --git a/test/automated/simple-test.el b/test/automated/simple-test.el index a9c4d67556e..8da575d5d97 100644 --- a/test/automated/simple-test.el +++ b/test/automated/simple-test.el @@ -26,6 +26,7 @@ (debug t)) `(with-temp-buffer (emacs-lisp-mode) + (setq indent-tabs-mode nil) (insert "(a b") (save-excursion (insert " c d)")) ,@body |