commit 43cacc31be36f62034b4a163d05b56de1ef1bdf9 (HEAD, refs/remotes/origin/master) Author: Eli Zaretskii Date: Sun Dec 24 09:31:32 2023 +0200 ; * src/eval.c (Fdefvar): Doc fix (bug#67991). diff --git a/src/eval.c b/src/eval.c index 30edaccdb62..5ae56292c75 100644 --- a/src/eval.c +++ b/src/eval.c @@ -792,8 +792,7 @@ DEFUN ("defvar", Fdefvar, Sdefvar, 1, UNEVALLED, 0, You are not required to define a variable in order to use it, but defining it lets you supply an initial value and documentation, which can be referred to by the Emacs help facilities and other programming -tools. The `defvar' form also declares the variable as \"special\", -so that it is always dynamically bound even if `lexical-binding' is t. +tools. If SYMBOL's value is void and the optional argument INITVALUE is provided, INITVALUE is evaluated and the result used to set SYMBOL's @@ -801,6 +800,13 @@ DEFUN ("defvar", Fdefvar, Sdefvar, 1, UNEVALLED, 0, buffer-local values are not affected. If INITVALUE is missing, SYMBOL's value is not set. +If INITVALUE is provided, the `defvar' form also declares the variable +as \"special\", so that it is always dynamically bound even if +`lexical-binding' is t. If INITVALUE is missing, the form marks the +variable \"special\" locally (i.e., within the current +lexical scope, or the current file, if the form is at top-level), +and does nothing if `lexical-binding' is nil. + If SYMBOL is let-bound, then this form does not affect the local let binding but the toplevel default binding instead, like `set-toplevel-default-binding`. commit b7fc3ab787d8dd926e1912e51e99f0efcf57cb02 Author: Po Lu Date: Sun Dec 24 15:21:24 2023 +0800 Introduce a toolbar for Log Edit mode * etc/NEWS: Announce new change. * etc/images/README: List the sources of the new image files. * etc/images/commit.xpm: * etc/images/commit.pbm: * etc/images/gen-changelog.xpm: * etc/images/gen-changelog.pbm: * etc/images/ins-changelog.xpm: * etc/images/ins-changelog.pbm: * etc/images/load-changelog.xpm: * etc/images/load-changelog.pbm: * etc/images/view-diff.xpm: New files. * lisp/vc/log-edit.el (log-edit-menu): Insert a menu item for "Generate ChangeLog". (log-edit-tool-bar-map): New keymap. (log-edit-mode): Install this keymap as the tool bar map. diff --git a/etc/NEWS b/etc/NEWS index 6df17aa3f0a..f82564946b7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -468,6 +468,11 @@ you can add this to your init script: ** VC +--- +*** Log-Edit buffers now display a tool bar. +This tool bar contains items for committing log entries and editing or +generating log entries, among other editing operations. + --- *** New user option 'vc-git-shortlog-switches'. This is a string or a list of strings that specifies the Git log diff --git a/etc/images/README b/etc/images/README index 5886f641536..71115540344 100644 --- a/etc/images/README +++ b/etc/images/README @@ -67,21 +67,25 @@ Emacs images and their source in the GNOME icons stock/ directory: attach.xpm document/stock_attach bookmark_add.xpm actions/bookmark_add cancel.xpm slightly modified generic/stock_stop - connect.xpm net/stock_connect + commit.xpm code/stock_run connect-to-url.xpm net/stock_connect-to-url + connect.xpm net/stock_connect contact.xpm net/stock_contact data-save.xpm data/stock_data-save delete.xpm generic/stock_delete describe.xpm generic/stock_properties disconnect.xpm net/stock_disconnect exit.xpm generic/stock_exit + gen-changelog.xpm text/stock_autoformat + ins-changelog.xpm form/stock_show-form-dialog + load-changelog.xpm text/stock_insert_endnote lock-broken.xpm data/stock_lock-broken lock-ok.xpm data/stock_lock-ok lock.xpm data/stock_lock - redo.xpm generic/stock_redo - search-replace.xpm slightly modified generic/stock_search-and-replace next-page.xpm navigation/stock_next-page + redo.xpm generic/stock_redo refresh.xpm generic/stock_refresh + search-replace.xpm slightly modified generic/stock_search-and-replace separator.xpm ? show.xpm slightly modified document/stock_new sort-ascending.xpm slightly modified data/stock_sort-ascending @@ -89,6 +93,7 @@ Emacs images and their source in the GNOME icons stock/ directory: sort-criteria.xpm data/stock_sort-criteria sort-descending.xpm slightly modified data/stock_sort-descending sort-row-ascending.xpm data/stock_sort-row-ascending + view-diff.xpm text/stock_list_enum-restart zoom-in.xpm navigation/stock_zoom-in zoom-out.xpm navigation/stock_zoom-out diff --git a/etc/images/commit.pbm b/etc/images/commit.pbm new file mode 100644 index 00000000000..11fe690ac1b Binary files /dev/null and b/etc/images/commit.pbm differ diff --git a/etc/images/commit.xpm b/etc/images/commit.xpm new file mode 100644 index 00000000000..1730f155811 --- /dev/null +++ b/etc/images/commit.xpm @@ -0,0 +1,101 @@ +/* XPM */ +static char *commit[] = { +/* columns rows colors chars-per-pixel */ +"24 24 71 1 ", +" c None", +". c black", +"X c gray13", +"o c gray14", +"O c #252525", +"+ c gray25", +"@ c gray33", +"# c #555555", +"$ c #565656", +"% c #5A5A5A", +"& c #5D5D5D", +"* c gray40", +"= c #6C6C6C", +"- c #DF421E", +"; c #46A046", +": c #625B81", +"> c #887FA3", +", c #848484", +"< c gray53", +"1 c #888888", +"2 c #8E8E8E", +"3 c #979797", +"4 c #9A9A9A", +"5 c #A0A0A0", +"6 c gray65", +"7 c #A9A9A9", +"8 c #AEAEAE", +"9 c gray75", +"0 c #BBB6CA", +"q c #C2C2C1", +"w c gray76", +"e c #C3C3C2", +"r c #C3C3C3", +"t c gray77", +"y c #C7C7C6", +"u c #C8C8C8", +"i c gray79", +"p c #C5C1D2", +"a c #CAC6D6", +"s c gray84", +"d c #D8D8D8", +"f c gray88", +"g c #E1E1E1", +"h c #E6E6E6", +"j c #EDEDEB", +"k c #EEEEED", +"l c #EFEFEF", +"z c #ECEAF0", +"x c #ECEBF0", +"c c #F0EFF3", +"v c gray94", +"b c #F1F1F0", +"n c #F2F2F1", +"m c #F4F4F3", +"M c #F4F3F6", +"N c #F5F5F4", +"B c gray96", +"V c #F6F6F5", +"C c #F6F6F6", +"Z c gray97", +"A c #F8F8F7", +"S c #F7F6F8", +"D c #F8F8F8", +"F c #F9F9F9", +"G c gray98", +"H c #FCFCFB", +"J c gray99", +"K c #FDFDFC", +"L c #FDFDFD", +"P c #FEFEFE", +"I c white", +/* pixels */ +" ...... ", +" .xx00. ", +" ..xp>>..", +" .Spa>>>.", +"+++++++++## .Mp>>. ", +"IIIIIIIIIGs. ", +"IIIIIIIIIGhv5. .. ", +"IIIIIIIIIGdIB3o ", +"IIIIIIIIIBiIIg1X ", +";:IIIIIIIB9gsiw2 ", +"IIIIIIIIHB7*&#%<. ", +":::G::::GBvsy64=. ", +"GGGGGGGGGGGGGGG8. ", +"--::G:::GGGGGGGw. ", +"GGGGGGGGGGGGGGGy. ", +"::A::AAAAAAAAAAy. ", +"BBBBBBBBBBBBBBBy. ", +"BBBBBBBBBBBBBBBw. ", +":mmmmmmmmmmmmmmw. ", +"vvvvvvvvvvvvvvvw. ", +"---v:v:::v:::vvw. ", +"lllllllllllllllw. ", +"::::l--:lllllllw. ", +"jjjjjjjjjjjjjjjw. " +}; diff --git a/etc/images/gen-changelog.pbm b/etc/images/gen-changelog.pbm new file mode 100644 index 00000000000..40bea125b06 Binary files /dev/null and b/etc/images/gen-changelog.pbm differ diff --git a/etc/images/gen-changelog.xpm b/etc/images/gen-changelog.xpm new file mode 100644 index 00000000000..65ea7c16f04 --- /dev/null +++ b/etc/images/gen-changelog.xpm @@ -0,0 +1,152 @@ +/* XPM */ +static char *gen_changelog[] = { +/* columns rows colors chars-per-pixel */ +"24 24 122 2 ", +" c None", +". c black", +"X c gray10", +"o c #353535", +"O c #442D0E", +"+ c #5E4417", +"@ c #7D5A22", +"# c #645435", +"$ c #464646", +"% c #505050", +"& c gray32", +"* c #535353", +"= c gray33", +"- c #585858", +"; c gray35", +": c #675E46", +"> c gray39", +", c #6E6E6C", +"< c gray43", +"1 c gray44", +"2 c #787775", +"3 c #797979", +"4 c #7B7B7B", +"5 c #88601F", +"6 c #A27E36", +"7 c #9A8558", +"8 c #9F8B5F", +"9 c #A09069", +"0 c #BAA069", +"q c #C7AF7A", +"w c #CCB176", +"e c #868583", +"r c #868686", +"t c gray53", +"y c #8B8A86", +"u c #888888", +"i c #898989", +"p c #8B8B88", +"a c gray54", +"s c #8B8B8B", +"d c #8C8C89", +"f c gray55", +"g c #8D8D8D", +"h c #8E8E8E", +"j c gray56", +"k c #909090", +"l c gray57", +"z c #929292", +"x c #939393", +"c c #969592", +"v c gray58", +"b c #959595", +"n c #979797", +"m c #9B9996", +"M c #9C9B97", +"N c #B8B39B", +"B c #A4A4A4", +"V c gray65", +"C c #A8A7A3", +"Z c #AAAAAA", +"A c #B0AFAC", +"S c gray70", +"D c #B4B4B4", +"F c #B6B6B6", +"G c #C0BFBD", +"H c #D6C08E", +"J c #D9C28B", +"K c #DEC58D", +"L c #D8C291", +"P c #DFCA96", +"I c #E1CC99", +"U c #C2C1BD", +"Y c #F3E5BE", +"T c #C5C5C5", +"R c #C6C6C6", +"E c gray79", +"W c #CACACA", +"Q c gray80", +"! c #CECECE", +"~ c #D2D0D0", +"^ c #DBDAD8", +"/ c gray86", +"( c gainsboro", +") c #DDDDDD", +"_ c #F4E7C2", +"` c #EBE8D3", +"' c gray88", +"] c #E1E1E1", +"[ c #E2E2E2", +"{ c gray89", +"} c #E4E4E4", +"| c gray90", +" . c #E6E6E6", +".. c #E7E7E7", +"X. c #EAE8E3", +"o. c gray91", +"O. c #E9E9E9", +"+. c #EAEAEA", +"@. c gray92", +"#. c #EFEDE9", +"$. c #ECECEC", +"%. c gray93", +"&. c #EEEEEE", +"*. c #EFEFEF", +"=. c #FEFCE8", +"-. c #FEFEED", +";. c gray94", +":. c #F1F1F1", +">. c gray95", +",. c #F3F3F3", +"<. c #F4F4F4", +"1. c gray96", +"2. c #F6F6F6", +"3. c gray97", +"4. c #F8F8F8", +"5. c #F9F9F9", +"6. c gray98", +"7. c #FBFBFB", +"8. c gray99", +"9. c #FDFDFD", +"0. c #FEFEFE", +"q. c white", +/* pixels */ +" . . . . . . . . . . . . . . . . . . . . ", +". [ >.>.>.>.>.>.>.<.<.<.<.<.<.<.<.<.<.<.) . ", +". >.[ [ [ [ [ } } } } o.o.o.o.o.$.$.$.$.$.. ", +". >.[ r r r r i i ; . & i o.o.$.$.$.$.>.>.. ", +". >.[ [ [ } } } [ . N . [ $.$.$.$.$.>.>.>.. ", +". >.[ r i i i i < . ` . = g g g g >.>.>.>.. ", +". >.} } } } } 3 . . -.. . 3 o.>.>.>.>.>.<.. ", +". >.} i i ; . . : _ =.6 # . . D >.>.>.<.<.. ", +". <.} } o.. 7 q J P Y w I K 8 . T <.<.<.<.. ", +". <.} i i & . . O @ 0 5 + . . n <.<.<.<.<.. ", +". <.o.o.o.o.[ k . . H . X $ . <.<.<.<.<.4.. ", +". <.o.i g g g g > . L . ; d C . <.<.4.4.4.. ", +". <.o.$.$.$.$.$.o.. 9 o . 2 G U . 4.4.4.4.. ", +". <.o.g g g g g g & . 1 T . i ~ C . 4.4.9.. ", +". <.$.$.$.$.>.>.>.>.T ) T T . M ^ A . 9.9.. ", +". <.$.g g g g k >.<.<.<.) ) S . C #.c . 9.. ", +". 4.>.>.>.>.>.<.<.<.<.4.4.[ E D . M X.e . . ", +". 4.>.k k k k k k k k n n n [ Q B . m X.< . ", +". >.>.<.<.<.<.<.<.4.4.4.4.9.9.} Q B . c X.2 . ", +". E $.4.<.<.<.4.4.4.4.4.9.9.9.9.} Q Z . y X.2 . ", +" . . . . . . . . . . . . . . . . . . . . y X.. ", +" . . ", +" ", +" " +}; diff --git a/etc/images/ins-changelog.pbm b/etc/images/ins-changelog.pbm new file mode 100644 index 00000000000..fb97cf7d5d8 Binary files /dev/null and b/etc/images/ins-changelog.pbm differ diff --git a/etc/images/ins-changelog.xpm b/etc/images/ins-changelog.xpm new file mode 100644 index 00000000000..24deee3c344 --- /dev/null +++ b/etc/images/ins-changelog.xpm @@ -0,0 +1,67 @@ +/* XPM */ +static char *ins_changelog[] = { +/* columns rows colors chars-per-pixel */ +"24 24 37 1 ", +" c None", +". c black", +"X c #161616", +"o c gray25", +"O c #4B4B49", +"+ c #5D5D5D", +"@ c #494066", +"# c #767676", +"$ c gray52", +"% c #A0A0A0", +"& c gray66", +"* c gray68", +"= c #BBBBBB", +"- c #BCBCBC", +"; c gray74", +": c #C1C1C1", +"> c gray76", +", c #C3C3C3", +"< c gray88", +"1 c #E2E2E2", +"2 c gray89", +"3 c #E4E4E4", +"4 c gray90", +"5 c #E6E6E6", +"6 c #E7E7E7", +"7 c gray91", +"8 c #EAEAEA", +"9 c gray92", +"0 c #ECECEC", +"q c gray93", +"w c #EEEEEE", +"e c #EFEFEF", +"r c gray94", +"t c #F1F1F1", +"y c #FBFBFB", +"u c #FDFDFD", +"i c #FEFEFE", +/* pixels */ +" ", +" ", +" @ @@ @@ @@ @@ ", +" @ ", +" @ ", +" @ @ ", +" @ ", +" ......... ", +" @ .iiiiiii2>. ", +" @ .itttttt>y&. ", +" .itttttt*#+o. ", +" @ .it@@@@t2$OX. ", +" @ .iteeeeeeee=. ", +" .ie@@@@@@@e=. ", +" @ .ieeeeeeee9=. ", +" @ .ie@@@@@@@9=. ", +" .i999999499=. ", +" @@ @@ @@.i9@@@@@@@4=. ", +" .i944444444=. ", +" .i4@@@@@@@4=. ", +" .i444444222=. ", +" .>-----====%. ", +" ........... ", +" " +}; diff --git a/etc/images/load-changelog.pbm b/etc/images/load-changelog.pbm new file mode 100644 index 00000000000..43f1a1b221f Binary files /dev/null and b/etc/images/load-changelog.pbm differ diff --git a/etc/images/load-changelog.xpm b/etc/images/load-changelog.xpm new file mode 100644 index 00000000000..6d317b6afa2 --- /dev/null +++ b/etc/images/load-changelog.xpm @@ -0,0 +1,82 @@ +/* XPM */ +static char *load_changelog[] = { +/* columns rows colors chars-per-pixel */ +"24 24 52 1 ", +" c None", +". c black", +"X c #434343", +"o c gray33", +"O c #DF421E", +"+ c #8B8B8B", +"@ c gray55", +"# c #8D8D8D", +"$ c #8E8E8E", +"% c gray56", +"& c #909090", +"* c gray57", +"= c #929292", +"- c #939393", +"; c gray58", +": c #959595", +"> c gray66", +", c #B7B7B7", +"< c gray74", +"1 c #C0C0C0", +"2 c gray79", +"3 c #CACACA", +"4 c gray84", +"5 c gray85", +"6 c #DADADA", +"7 c #DDDDDD", +"8 c #DFDFDF", +"9 c gray90", +"0 c gray91", +"q c #E9E9E9", +"w c #EAEAEA", +"e c gray92", +"r c #ECECEC", +"t c gray93", +"y c #EEEEEE", +"u c #EFEFEF", +"i c gray94", +"p c #F1F1F1", +"a c gray95", +"s c #F3F3F3", +"d c #F4F4F4", +"f c gray96", +"g c #F6F6F6", +"h c gray97", +"j c #F8F8F8", +"k c #F9F9F9", +"l c gray98", +"z c #FBFBFB", +"x c gray99", +"c c #FDFDFD", +"v c #FEFEFE", +"b c white", +/* pixels */ +" .. .. .. .. ", +" .d3..51..7>..d,.. ", +" .d00tttttiiiiddd4. ", +" .d0+$$$$$$&&&$jjt. ", +" .d00ttiiiidddjjX5. ", +" .d0$$$&9OOOOcjj........", +" .dttiiidddddjjjo7. .", +" .dttiiiddddddjjc5. .", +" .jiidddddjjjcccc7. .", +" .ji&&&&&&;;;;;cc7. .", +" .jiiiddddjjjjccc7. .", +" .ji&&&&&;;;;cccc7. .", +" .iiidddjjjjccccct. .", +" .3tjdjjjjjccccct<. .", +" ................ .", +" .", +" .", +" . .", +" .. .", +" OOOOOOOOOOOOO ......", +" OOOOOOOOOOOOO .. ", +" . ", +" ", +" " +}; diff --git a/etc/images/view-diff.pbm b/etc/images/view-diff.pbm new file mode 100644 index 00000000000..35aabdabb1e Binary files /dev/null and b/etc/images/view-diff.pbm differ diff --git a/etc/images/view-diff.xpm b/etc/images/view-diff.xpm new file mode 100644 index 00000000000..3ebd0b3002b --- /dev/null +++ b/etc/images/view-diff.xpm @@ -0,0 +1,93 @@ +/* XPM */ +static char *view_diff[] = { +/* columns rows colors chars-per-pixel */ +"24 24 63 1 ", +" c None", +". c black", +"X c gray43", +"o c #6F6F6F", +"O c gray44", +"+ c #717171", +"@ c #727272", +"# c gray45", +"$ c #747474", +"% c gray46", +"& c #767676", +"* c #777777", +"= c gray47", +"- c #DF421E", +"; c #E3846E", +": c #838383", +"> c gray74", +", c #E19989", +"< c #E29A8A", +"1 c #E39B8B", +"2 c #E59C8B", +"3 c #E49C8C", +"4 c #E4AB9E", +"5 c #E8AEA1", +"6 c #C5C5C5", +"7 c gray79", +"8 c gray81", +"9 c #DADADA", +"0 c gray86", +"q c #DDDDDD", +"w c #EAD4CE", +"e c gray88", +"r c #E1E1E1", +"t c #E2E2E2", +"y c gray89", +"u c #E4E4E4", +"i c gray90", +"p c #E6E6E6", +"a c #E7E7E7", +"s c gray91", +"d c #E9E9E9", +"f c #EAEAEA", +"g c gray92", +"h c #ECECEC", +"j c gray93", +"k c #EEEEEE", +"l c #EFEFEF", +"z c gray94", +"x c #F1F1F1", +"c c gray95", +"v c #F3F3F3", +"b c #F4F4F4", +"n c gray96", +"m c #F6F6F6", +"M c gray97", +"N c #F8F8F8", +"B c #F9F9F9", +"V c gray98", +"C c #FBFBFB", +"Z c gray99", +"A c #FDFDFD", +"S c #FEFEFE", +"D c white", +/* pixels */ +" .................... ", +".tcccccccbbbbbbbbbbbq. ", +".ctttttiiiidddddhhhhh. ", +".ctttti8Xidddddhhhhcc. ", +".cttti8XXdd+++++++ccc. ", +".ctiiiiiXddhhhhhhcccc. ", +".c,---id+dd++++++$ccb. ", +".ci,--dd+dhhhhchcccbb. ", +".bi-,-dddhh+++$cbcbbb. ", +".b-4d3dhhhhhccccbbbbb. ", +".b-ddhhhhhhccccbbbNNN. ", +".b-ddhhhhccccbbbbNNNN. ", +".b;-whh6$0cccbbbbNNNN. ", +".bd2-5h+c$b:$$$$$=NNZ. ", +".bhhhhccq$bbbbbNNNNZZ. ", +".bhhhcc0$qb$$$$==NZZZ. ", +".Nccccc$$$bNNNNNZZZZZ. ", +".NcccbbbbbNNNZZZZZZZZ. ", +".ccbbbbbbNNNZZZZZZZZh. ", +".7hNbbbNNNNNZZZZZZZh>. ", +" .................... ", +" ", +" ", +" " +}; diff --git a/lisp/vc/log-edit.el b/lisp/vc/log-edit.el index 39e0799ba73..c2665c802f6 100644 --- a/lisp/vc/log-edit.el +++ b/lisp/vc/log-edit.el @@ -76,6 +76,8 @@ log-edit-menu "--" ["Insert ChangeLog" log-edit-insert-changelog :help "Insert a log message by looking at the ChangeLog"] + ["Generate ChangeLog" log-edit-generate-changelog-from-diff + :help "Generate a log message from the diff and insert it into this buffer"] ["Add to ChangeLog" log-edit-add-to-changelog :help "Insert this log message into the appropriate ChangeLog file"] "--" @@ -93,6 +95,65 @@ log-edit-menu ["Search comment backward" log-edit-comment-search-backward :help "Search backwards through comment history for substring match of str"])) +(defvar log-edit-tool-bar-map + (let ((map (make-sparse-keymap))) + (tool-bar-local-item-from-menu 'find-file "new" map + nil :label "New File" + :vert-only t) + (tool-bar-local-item-from-menu 'menu-find-file-existing "open" map + nil :label "Open" :vert-only t) + (tool-bar-local-item-from-menu 'dired "diropen" map nil :vert-only t) + (tool-bar-local-item-from-menu 'kill-this-buffer "close" map nil + :vert-only t) + (define-key-after map [separator-1] menu-bar-separator) + (tool-bar-local-item-from-menu 'log-edit-done "commit" + map log-edit-mode-map :vert-only t + :help + "Complete the actual action") + (define-key-after map [separator-2] menu-bar-separator) + (tool-bar-local-item-from-menu 'log-edit-insert-changelog + "ins-changelog" + map log-edit-mode-map :vert-only t + :help + "Complete the actual action") + (tool-bar-local-item-from-menu 'log-edit-insert-changelog + "load-changelog" + map log-edit-mode-map :vert-only t + :help + "Insert log message from ChangeLog file") + (tool-bar-local-item-from-menu 'log-edit-generate-changelog-from-diff + "gen-changelog" + map log-edit-mode-map :vert-only t + :help + "Generate a log message from diff") + (tool-bar-local-item-from-menu 'log-edit-add-to-changelog + "ins-changelog" + map log-edit-mode-map :vert-only t + :help + "Insert this log message into the ChangeLog") + (define-key-after map [separator-3] menu-bar-separator) + (tool-bar-local-item-from-menu 'log-edit-show-diff + "view-diff" + map log-edit-mode-map :vert-only t + :help + "View the diff for the files to be committed") + (tool-bar-local-item-from-menu 'log-edit-show-files + "info" + map log-edit-mode-map :vert-only t + :help + "View the list of files to be committed") + (define-key-after map [separator-4] menu-bar-separator) + (tool-bar-local-item-from-menu 'undo "undo" map nil) + (define-key-after map [separator-5] menu-bar-separator) + (tool-bar-local-item-from-menu (lookup-key menu-bar-edit-menu [cut]) + "cut" map nil) + (tool-bar-local-item-from-menu (lookup-key menu-bar-edit-menu [copy]) + "copy" map nil) + (tool-bar-local-item-from-menu (lookup-key menu-bar-edit-menu [paste]) + "paste" map nil) + map) + "Like the default `tool-bar-map', but with additions for Log-Edit mode.") + (defcustom log-edit-confirm 'changed "If non-nil, `log-edit-done' will request confirmation. If `changed', only request confirmation if the list of files has @@ -511,7 +572,9 @@ log-edit-mode (setq-local fill-paragraph-function #'log-edit-fill-entry) (make-local-variable 'log-edit-comment-ring-index) (add-hook 'kill-buffer-hook 'log-edit-remember-comment nil t) - (hack-dir-local-variables-non-file-buffer)) + (hack-dir-local-variables-non-file-buffer) + ;; Replace the tool bar map with `log-edit-tool-bar-map'. + (setq-local tool-bar-map log-edit-tool-bar-map)) (defun log-edit--insert-filled-defuns (func-names) "Insert FUNC-NAMES, following ChangeLog formatting." commit 5c3ff1494b69bf45b99125f2423174222badfa43 Author: Dmitry Gutov Date: Sat Dec 23 22:53:35 2023 +0200 jit-lock-force-redisplay: Make it work * lisp/jit-lock.el (jit-lock-force-redisplay): Make sure the buffer change is really performed (bug#66732). diff --git a/lisp/jit-lock.el b/lisp/jit-lock.el index d0522d6a791..70277545495 100644 --- a/lisp/jit-lock.el +++ b/lisp/jit-lock.el @@ -500,6 +500,7 @@ jit-lock-force-redisplay (setq start (point-min) end (max start end))) ;; Don't cause refontification (it's already been done), but just do ;; some random buffer change, so as to force redisplay. + (put-text-property start end 'fontified nil) (put-text-property start end 'fontified t))))) ;;; Stealth fontification. commit 5fb9d6c5e72e8a21b8426a3fd5ec5c8f4679d8b6 Author: F. Jason Park Date: Fri Dec 22 18:18:20 2023 -0800 Optionally continue on error in erc-auth-source-search * doc/misc/erc.texi (auth-source): Add new "Troubleshooting" subsection. * lisp/erc/erc.el (erc-open): Initialize markers before determining session parameters. Otherwise, functions that rely on `erc-inset-marker' being non-nil, like `erc-check-text-conversion', may fail during auth-source lookups. (erc-auth-source-search): When non-interactive, ask the user whether to continue connecting anyway. (Bug#67978) diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi index 131e02555d1..61a4c9e1438 100644 --- a/doc/misc/erc.texi +++ b/doc/misc/erc.texi @@ -1674,6 +1674,7 @@ auth-source machine irc.example.net login mynick password sEcReT @end example +@anchor{auth-source Server Password} @subsubheading Server Passwords When retrieving passwords to accompany the IRC @samp{PASS} command (@pxref{password parameter}), ERC asks auth-source to match the @@ -1723,10 +1724,7 @@ auth-source @subsubheading Default query behavior When preparing entries for your backend, it may help to get a feel for how ERC and its modules conduct searches, especially when exploring a -new context, such as channel keys. (Hint: in such situations, try -temporarily setting the variable @code{auth-source-debug} to @code{t} -and checking @file{*Messages*} periodically for insights into how -auth-source is operating.) Overall, though, ERC tries to be +new context, such as channel keys. Overall, though, ERC tries to be consistent in performing queries across various authentication contexts. Here's what to expect with respect to the @samp{host} field, which, by default, most heavily influences the fate of a query: @@ -1810,6 +1808,33 @@ auth-source @samp{user} field (for example, @samp{login "#fsf"}, in netrc's case). The actual key goes in the @samp{password} (or @samp{secret}) field. +@anchor{auth-source Troubleshooting} +@subheading Troubleshooting +By default, ERC queries @code{auth-source} for channel keys and server +passwords (@pxref{auth-source Server Password}), as well as other, +module-specific credentials. In general, if you're having trouble +calling @code{auth-source-search} in a custom query function, like +@code{erc-auth-source-server-function}, try temporarily setting the +variable @code{auth-source-debug} to @code{t} and checking +@file{*Messages*} periodically for insights into how +@code{auth-source} is operating. + +If you're using a @acronym{GPG}-encrypted file and find that +customizing one of the function-valued query options doesn't solve +your problem, explore options @code{epg-pinentry-mode} and +@code{epg-debug} in the @code{epg} Custom group (@pxref{GnuPG +Pinentry,,, epa, EasyPG Assistant}). Additionally, keep an eye out +for an @file{*Error*} buffer, which may contain more specific clues +about your situation. If you use the libsecrets integration +(@pxref{Secret Service API,,, auth, Emacs auth-source}) with something +like GNOME Keyring, you may need to check the ``remember'' box in the +passphrase popup dialog to avoid being prompted for confirmation every +time you run ERC. If it doesn't work at first, try logging out. And +when in doubt, try using the Emacs command @code{secrets-show-secrets} +to browse the @samp{Login} keyring. There should be a +@samp{GnuPG/stored-by} entry with a value of @samp{GnuPG Pinentry} or +similar. + @node display-buffer @subsection display-buffer @cindex display-buffer diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 6eee8bcae92..ab9c769cbbf 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -2542,8 +2542,8 @@ erc-open (when erc-log-p (get-buffer-create (concat "*ERC-DEBUG: " server "*")))) - (erc-determine-parameters server port nick full-name user passwd) (erc--initialize-markers old-point continued-session) + (erc-determine-parameters server port nick full-name user passwd) (save-excursion (run-mode-hooks) (dolist (mod (car delayed-modules)) (funcall mod +1)) (dolist (var (cdr delayed-modules)) (set var nil))) @@ -4400,11 +4400,22 @@ erc--auth-source-search (plist-get (car sorted) :secret)))) (defun erc-auth-source-search (&rest plist) - "Call `auth-source-search', possibly with keyword params in PLIST." + "Call `auth-source-search', possibly with keyword params in PLIST. +If the search signals an error before returning, `warn' the user +and ask whether to continue connecting anyway." ;; These exist as separate helpers in case folks should find them ;; useful. If that's you, please request that they be exported. - (apply #'erc--auth-source-search - (apply #'erc--auth-source-determine-params-merge plist))) + (condition-case err + (apply #'erc--auth-source-search + (apply #'erc--auth-source-determine-params-merge plist)) + (error + (erc--lwarn '(erc auth-source) :error + "Problem querying `auth-source': %S. See %S for more." + (error-message-string err) + '(info "(erc) auth-source Troubleshooting")) + (when (or noninteractive + (not (y-or-n-p "Ignore auth-source error and continue? "))) + (signal (car err) (cdr err)))))) (defun erc-server-join-channel (server channel &optional secret) "Join CHANNEL, optionally with SECRET. commit 9cd47017c705fe0efe8f42c143807a489ed69016 Author: F. Jason Park Date: Tue Dec 19 22:33:48 2023 -0800 Fix overlapping logs from erc-truncate-buffer-on-save * lisp/erc/erc-button.el (erc-button--display-error-notice-with-keys): Currently, internal "error notices" do not have timestamps. However, this causes alignment issues for non-`fill-wrap' users of left-sided stamps. The heuristic used by this change for detecting such stamps is weak and prone to false negatives. * lisp/erc/erc-log.el (erc-log-mode, erc-log-enable): Set explicit depth for `erc--pre-clear-functions' to 50. (erc-save-buffer-in-logs): Fix partial regression in which redundant text would appear in logs that have undergone truncation via an interactive call to this command when the deprecated option `erc-truncate-on-save' is non-nil. * lisp/erc/erc-stamp.el (erc-stamp-mode, erc-stamp-enable): Set depth for `erc--pre-clear-functions' to 40. (erc-stamp--reset-on-clear): Only add `erc-stamp--insert-date-hook' when `erc-stamp--date-mode' is active. * lisp/erc/erc.el (erc-cmd-CLEAR): Rework to honor but improve upon the old behavior when called from lisp. Do this by attempting to find the beginning of the current message and excluding it from the truncated portion of the buffer. A NEWS entry describing this behavior already exists for 5.6. * test/lisp/erc/erc-scenarios-log.el (erc-scenarios-log--save-buffer-in-logs/truncate-on-save): New test. These changes originate from bug#60936. diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el index a62dd520860..c290e76843c 100644 --- a/lisp/erc/erc-button.el +++ b/lisp/erc/erc-button.el @@ -829,6 +829,7 @@ erc-button--display-error-notice-with-keys to STRINGS. If STRINGS contains any trailing non-nil non-strings, concatenate leading string members before applying `format'. Otherwise, just concatenate everything." + (defvar erc-stamp--skip) (let* ((buffer (if (bufferp maybe-buffer) maybe-buffer (when (stringp maybe-buffer) @@ -844,8 +845,10 @@ erc-button--display-error-notice-with-keys (push head strings)) #'format)) (string (apply op strings)) - (erc-insert-modify-hook (remove 'erc-add-timestamp - erc-insert-modify-hook)) + ;; Avoid timestamps unless left-sided. + (erc-stamp--skip (or (bound-and-true-p erc-stamp--display-margin-mode) + (not (fboundp 'erc-timestamp-offset)) + (zerop (erc-timestamp-offset)))) (erc-insert-post-hook (cons (lambda () (setq string (buffer-substring (point-min) diff --git a/lisp/erc/erc-log.el b/lisp/erc/erc-log.el index 79fece5779e..5efde6cad11 100644 --- a/lisp/erc/erc-log.el +++ b/lisp/erc/erc-log.el @@ -231,7 +231,7 @@ log (add-hook 'erc-part-hook #'erc-conditional-save-buffer) ;; append, so that 'erc-initialize-log-marker runs first (add-hook 'erc-connect-pre-hook #'erc-log-setup-logging 'append) - (add-hook 'erc--pre-clear-functions #'erc-save-buffer-in-logs) + (add-hook 'erc--pre-clear-functions #'erc-save-buffer-in-logs 50) (dolist (buffer (erc-buffer-list)) (erc-log-setup-logging buffer)) (erc--modify-local-map t "C-c C-l" #'erc-save-buffer-in-logs)) @@ -430,7 +430,8 @@ erc-save-buffer-in-logs (if (and erc-truncate-buffer-on-save (called-interactively-p 'interactive)) (let ((erc-log--save-in-progress-p t)) - (erc-cmd-CLEAR) + (save-excursion (goto-char erc-insert-marker) + (erc-cmd-CLEAR)) (erc-button--display-error-notice-with-keys (erc-server-buffer) "Option `%s' is deprecated." " Use /CLEAR instead." 'erc-truncate-buffer-on-save)) diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el index 9ca3ea320a0..a65b564ba6c 100644 --- a/lisp/erc/erc-stamp.el +++ b/lisp/erc/erc-stamp.el @@ -182,7 +182,7 @@ stamp (add-hook 'erc-insert-modify-hook #'erc-add-timestamp 70) (add-hook 'erc-send-modify-hook #'erc-add-timestamp 70) (add-hook 'erc-mode-hook #'erc-stamp--recover-on-reconnect) - (add-hook 'erc--pre-clear-functions #'erc-stamp--reset-on-clear) + (add-hook 'erc--pre-clear-functions #'erc-stamp--reset-on-clear 40) (unless erc--updating-modules-p (erc-buffer-do #'erc-stamp--setup))) ((remove-hook 'erc-mode-hook #'erc-munge-invisibility-spec) (remove-hook 'erc-insert-modify-hook #'erc-add-timestamp) @@ -973,8 +973,9 @@ erc-stamp--update-saved-position (defun erc-stamp--reset-on-clear (pos) "Forget last-inserted stamps when POS is at insert marker." (when (= pos (1- erc-insert-marker)) - (add-hook 'erc-stamp--insert-date-hook - #'erc-stamp--update-saved-position 0 t) + (when erc-stamp--date-mode + (add-hook 'erc-stamp--insert-date-hook + #'erc-stamp--update-saved-position 0 t)) (setq erc-timestamp-last-inserted nil erc-timestamp-last-inserted-left nil erc-timestamp-last-inserted-right nil))) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 64629026704..6eee8bcae92 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -4160,12 +4160,16 @@ erc--pre-clear-functions Called with position indicating boundary of interval to be excised.") (defun erc-cmd-CLEAR () - "Clear the window content." - (let ((inhibit-read-only t)) - (run-hook-with-args 'erc--pre-clear-functions (1- erc-insert-marker)) - ;; Ostensibly, `line-beginning-position' is for use in lisp code. - (delete-region (point-min) (min (line-beginning-position) - (1- erc-insert-marker)))) + "Clear messages in current buffer after informing active modules. +Expect modules to perform housekeeping tasks to withstand the +disruption. When called from lisp code, only clear messages up +to but not including the one occupying the current line." + (with-silent-modifications + (let ((max (if (>= (point) erc-insert-marker) + (1- erc-insert-marker) + (or (erc--get-inserted-msg-bounds 'beg) (pos-bol))))) + (run-hook-with-args 'erc--pre-clear-functions max) + (delete-region (point-min) max))) t) (put 'erc-cmd-CLEAR 'process-not-needed t) diff --git a/test/lisp/erc/erc-scenarios-log.el b/test/lisp/erc/erc-scenarios-log.el index cd28ea54b2e..cff88d59c85 100644 --- a/test/lisp/erc/erc-scenarios-log.el +++ b/test/lisp/erc/erc-scenarios-log.el @@ -206,4 +206,59 @@ erc-scenarios-log--truncate (erc-truncate-mode -1) (when noninteractive (delete-directory tempdir :recursive)))) +(defvar erc-insert-timestamp-function) +(declare-function erc-insert-timestamp-left "erc-stamp" (string)) + +(ert-deftest erc-scenarios-log--save-buffer-in-logs/truncate-on-save () + :tags '(:expensive-test) + (erc-scenarios-common-with-cleanup + ((erc-scenarios-common-dialog "base/assoc/bouncer-history") + (dumb-server (erc-d-run "localhost" t 'foonet)) + (tempdir (make-temp-file "erc-tests-log." t nil nil)) + (erc-log-channels-directory tempdir) + (erc-modules (cons 'log erc-modules)) + (port (process-contact dumb-server :service)) + (erc-truncate-buffer-on-save t) + (logchan (expand-file-name (format "#chan!tester@127.0.0.1:%d.txt" port) + tempdir)) + (erc-server-flood-penalty 0.1) + (erc-insert-timestamp-function #'erc-insert-timestamp-left) + (expect (erc-d-t-make-expecter))) + + (unless noninteractive + (add-hook 'kill-emacs-hook + (lambda () (delete-directory tempdir :recursive)))) + + (ert-info ("Connect to foonet") + (with-current-buffer (erc :server "127.0.0.1" + :port port + :nick "tester" + :password "foonet:changeme" + :full-name "tester") + (should (string= (buffer-name) (format "127.0.0.1:%d" port))))) + + (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan")) + (funcall expect 10 " [07:04:10] hi everyone") + (should-not (file-exists-p logchan)) + ;; Simulate an M-x erc-save-buffer-in-logs RET + (cl-letf (((symbol-function 'called-interactively-p) #'always)) + (call-interactively #'erc-save-buffer-in-logs)) + (should (file-exists-p logchan)) + (funcall expect 10 " bob: As't please your lordship") + (erc-save-buffer-in-logs) + ;; Not truncated when called by lisp code. + (should (> (buffer-size) 400))) + + (ert-info ("No double entries") + (with-temp-buffer + (insert-file-contents logchan) + (funcall expect 0.1 "hi everyone") + (funcall expect -0.1 "hi everyone") + (funcall expect 0.1 "Playback Complete") + (funcall expect -0.1 "Playback Complete") + (funcall expect 10 " bob: As't"))) + + (erc-log-mode -1) + (when noninteractive (delete-directory tempdir :recursive)))) + ;;; erc-scenarios-log.el ends here commit 34fe0b5c87ca991436d999d451276838529c96c2 Author: F. Jason Park Date: Mon Dec 18 20:50:26 2023 -0800 Replace some uses of erc-error * lisp/erc/erc-button.el (erc-button--display-error-notice-with-keys-and-warn): Use `erc--lwarn' so the warnings buffer is overridable for testing. * lisp/erc/erc-sasl.el (erc-sasl-mode, erc-sasl-enable): Signal an `error' instead of calling `erc-error', which continues execution. In this special case, the session cannot continue initializing, since connection registration can't reasonably be expected to complete successfully. (erc-sasl--destroy): Don't run `erc-quit-hook', and issue a warning of level `:error' to get users' attention instead of calling `ding'. * lisp/erc/erc-speedbar.el (erc-speedbar--emulate-sidebar-set-window-preserve-size): Don't set window parameters. Doing this basically made `erc-speedbar-toggle-nicknames-window-lock' unusable. (erc-speedbar--toggle-nicknames-sidebar): Manually unlock the window after toggling. (erc-nickbar-mode, erc-nickbar-enable, erc-nickbar-disable): Don't `ding' when called in a non-ERC buffer, and make sure to call `erc-speedbar--ensure' from an ERC buffer. Also, don't disable minor-mode var when speedbar buffer doesn't exist because that doesn't ensure it'll be created the next time around, and users may count on the activation state remaining consistent. (erc-speedbar-toggle-nicknames-window-lock): Make usable from lisp with explicit numeric arg. * lisp/erc/erc-status-sidebar.el (erc-bufbar-mode, erc-bufbar-enable): Only create the side window from an erc-mode buffer to ensure the ratio is preserved when burying the current buffer, e.g., with `custom-buffer-done'. * lisp/erc/erc.el (erc--warnings-buffer-name, erc--lwarn): New function, an analog of `lwarn', that allows for overriding the warnings buffer with the new variable `erc--warnings-buffer-name'. (erc-cmd-SERVER): Add comment. * test/lisp/erc/erc-scenarios-sasl.el (erc-scenarios-sasl--plain-fail): Expect warning instead of error. * test/lisp/erc/erc-scenarios-status-sidebar.el (erc-scenarios-status-sidebar--bufbar): Refresh when interactive as well. * test/lisp/erc/resources/sasl/plain-failed.eld: Expect EOF instead of "CAP END". (Bug#63595) diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el index d27aa299df2..a62dd520860 100644 --- a/lisp/erc/erc-button.el +++ b/lisp/erc/erc-button.el @@ -869,8 +869,8 @@ erc-button--display-error-notice-with-keys-and-warn (with-syntax-table lisp-mode-syntax-table (skip-syntax-forward "^-")) (forward-char) - (display-warning - 'erc (buffer-substring-no-properties (point) (point-max)))))) + (erc--lwarn + 'erc :warning (buffer-substring-no-properties (point) (point-max)))))) (provide 'erc-button) diff --git a/lisp/erc/erc-sasl.el b/lisp/erc/erc-sasl.el index 8ecce7aef31..ae057f939a3 100644 --- a/lisp/erc/erc-sasl.el +++ b/lisp/erc/erc-sasl.el @@ -332,8 +332,8 @@ sasl (client (erc-sasl--create-client mech))) (unless client (erc-display-error-notice - nil (format "Unknown or unsupported SASL mechanism: %s" mech)) - (erc-error "Unknown or unsupported SASL mechanism: %s" mech)) + nil (format "Unknown or unsupported SASL mechanism: `%s'" mech)) + (error "Unknown or unsupported SASL mechanism: `%s'" mech)) (setf (erc-sasl--state-client erc-sasl--state) client)))) ((kill-local-variable 'erc-sasl--state) (kill-local-variable 'erc-sasl--options)) @@ -370,9 +370,10 @@ sasl (setq data (concat (substring data end) (and (= end 400) "+")))))))) (defun erc-sasl--destroy (proc) - (run-hook-with-args 'erc-quit-hook proc) + "Destroy process PROC and warn user that their settings are likely faulty." (delete-process proc) - (erc-error "Disconnected from %s; please review SASL settings" proc)) + (erc--lwarn 'erc-sasl :error + "Disconnected from %s; please review SASL settings" proc)) (define-erc-response-handler (902) "Handle an ERR_NICKLOCKED response." nil diff --git a/lisp/erc/erc-speedbar.el b/lisp/erc/erc-speedbar.el index 90d7376fc0c..91806f47e01 100644 --- a/lisp/erc/erc-speedbar.el +++ b/lisp/erc/erc-speedbar.el @@ -453,10 +453,7 @@ erc-speedbar--emulate-sidebar-set-window-preserve-size `(display-buffer-in-side-window . ((side . right) (window-width . ,erc-speedbar-nicknames-window-width))))) - (erc-status-sidebar-set-window-preserve-size) - (when-let ((window (get-buffer-window speedbar-buffer))) - (set-window-parameter window 'no-other-window nil) - (internal-show-cursor window t)))) + (erc-status-sidebar-set-window-preserve-size))) (defun erc-speedbar--status-sidebar-mode--unhook () "Remove hooks installed by `erc-status-sidebar-mode'." @@ -504,7 +501,8 @@ erc-speedbar--toggle-nicknames-sidebar (speedbar-set-mode-line-format))) (when (or (not force) (>= arg 0)) (with-selected-frame speedbar-frame - (erc-speedbar--emulate-sidebar-set-window-preserve-size))))) + (erc-speedbar--emulate-sidebar-set-window-preserve-size) + (erc-speedbar-toggle-nicknames-window-lock -1))))) (when-let (((or (not force) (>= arg 0))) (speedbar-frame-parameters (backquote-list* '(visibility . nil) @@ -522,7 +520,8 @@ erc-speedbar--toggle-nicknames-sidebar ;; Emacs in the meantime. (make-frame-invisible speedbar-frame) (select-frame (setq speedbar-frame (previous-frame))) - (erc-speedbar--emulate-sidebar-set-window-preserve-size)))) + (erc-speedbar--emulate-sidebar-set-window-preserve-size) + (erc-speedbar-toggle-nicknames-window-lock -1)))) (cl-assert (not (cdr (erc-speedbar--get-timers))) t)) (defun erc-speedbar--ensure (&optional force) @@ -563,12 +562,10 @@ nickbar (and-let* ((speedbar-buffer) (win (get-buffer-window speedbar-buffer 'all-frames)) ((eq speedbar-frame (window-frame win)))))) - (if speedbar-buffer - (erc-speedbar--ensure 'force) - (setq erc-nickbar-mode nil) - (when (derived-mode-p 'erc-mode) - (erc-error "Not initializing `erc-nickbar-mode' in %s" - (current-buffer)))))) + (when-let ((buf (or (and (derived-mode-p 'erc-mode) (current-buffer)) + (car (erc-buffer-filter #'erc--server-buffer-p))))) + (with-current-buffer buf + (erc-speedbar--ensure 'force))))) ((remove-hook 'erc--setup-buffer-hook #'erc-speedbar--ensure) (when erc-track-mode (setq erc-track--switch-fallback-blockers @@ -609,15 +606,21 @@ erc-speedbar--dframe-controlled ;; erc-speedbar.el resets this to nil. (setq speedbar-buffer nil))) -(defun erc-speedbar-toggle-nicknames-window-lock () - "Toggle whether nicknames window is selectable with \\[other-window]." - (interactive) +(defun erc-speedbar-toggle-nicknames-window-lock (arg) + "Toggle whether nicknames window is selectable with \\[other-window]. +When arg is a number, lock the window if non-negative, otherwise +unlock." + (interactive "P") (unless erc-nickbar-mode (user-error "`erc-nickbar-mode' inactive")) (when-let ((window (get-buffer-window speedbar-buffer))) - (let ((val (window-parameter window 'no-other-window))) - (set-window-parameter window 'no-other-window (not val)) - (message "nick-window: %s" (if val "selectable" "protected"))))) + (let ((val (cond ((natnump arg) t) + ((integerp arg) nil) + (t (not (window-parameter window + 'no-other-window)))))) + (set-window-parameter window 'no-other-window val) + (unless (numberp arg) + (message "nick-window: %s" (if val "protected" "selectable")))))) ;;;; Nicks integration diff --git a/lisp/erc/erc-status-sidebar.el b/lisp/erc/erc-status-sidebar.el index 98d5a321385..2cd74021fe7 100644 --- a/lisp/erc/erc-status-sidebar.el +++ b/lisp/erc/erc-status-sidebar.el @@ -257,12 +257,13 @@ bufbar " Add `track' to `erc-modules' to silence this message.")) (erc-track-mode +1)) (add-hook 'erc--setup-buffer-hook #'erc-status-sidebar--open) - (unless erc--updating-modules-p - (if (erc-with-server-buffer erc-server-connected) - (erc-status-sidebar--open) - (when (derived-mode-p 'erc-mode) - (erc-error "Not initializing `erc-bufbar-mode' in %s" - (current-buffer)))))) + ;; Preserve side-window dimensions after `custom-buffer-done'. + (when-let (((not erc--updating-modules-p)) + (buf (or (and (derived-mode-p 'erc-mode) (current-buffer)) + (car (erc-buffer-filter + (lambda () erc-server-connected)))))) + (with-current-buffer buf + (erc-status-sidebar--open)))) ((remove-hook 'erc--setup-buffer-hook #'erc-status-sidebar--open) (erc-status-sidebar-close 'all-frames) (when-let ((arg erc--module-toggle-prefix-arg) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 241e260e518..64629026704 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -2880,6 +2880,15 @@ erc-error (apply #'message args) (beep))) +(defvar erc--warnings-buffer-name nil + "Name of possibly existing alternate warnings buffer for unit tests.") + +(defun erc--lwarn (type level format-string &rest args) + "Issue a warning of TYPE and LEVEL with FORMAT-STRING and ARGS." + (let ((message (substitute-command-keys + (apply #'format-message format-string args)))) + (display-warning type message level erc--warnings-buffer-name))) + ;;; Debugging the protocol (defvar erc-debug-irc-protocol-time-format "%FT%T.%6N%z " @@ -5032,6 +5041,8 @@ erc-cmd-RECONNECT (put 'erc-cmd-RECONNECT 'process-not-needed t) +;; FIXME use less speculative error message or lose `condition-case', +;; since most connection failures don't signal anything. (defun erc-cmd-SERVER (server) "Connect to SERVER, leaving existing connection intact." (erc-log (format "cmd: SERVER: %s" server)) diff --git a/test/lisp/erc/erc-scenarios-sasl.el b/test/lisp/erc/erc-scenarios-sasl.el index ab652d72dd2..74075b1aaf3 100644 --- a/test/lisp/erc/erc-scenarios-sasl.el +++ b/test/lisp/erc/erc-scenarios-sasl.el @@ -149,23 +149,25 @@ erc-scenarios-sasl--plain-fail (erc-modules (cons 'sasl erc-modules)) (erc-sasl-password "wrong") (erc-sasl-mechanism 'plain) - (expect (erc-d-t-make-expecter)) - (buf nil)) + (erc--warnings-buffer-name "*ERC test warnings*") + (warnings-buffer (get-buffer-create erc--warnings-buffer-name)) + (expect (erc-d-t-make-expecter))) - (ert-info ("Connect") - (setq buf (erc :server "127.0.0.1" - :port port - :nick "tester" - :user "tester" - :full-name "tester")) - (let ((err (should-error - (with-current-buffer buf - (funcall expect 20 "Connection failed!"))))) - (should (string-search "please review" (cadr err))) - (with-current-buffer buf - (funcall expect 10 "Opening connection") - (funcall expect 20 "SASL authentication failed") - (should-not (erc-server-process-alive))))))) + (with-current-buffer (erc :server "127.0.0.1" + :port port + :nick "tester" + :user "tester" + :full-name "tester") + (funcall expect 10 "Opening connection") + (funcall expect 20 "SASL authentication failed") + (funcall expect 20 "Connection failed!") + (should-not (erc-server-process-alive))) + + (with-current-buffer warnings-buffer + (funcall expect 10 "please review SASL settings"))) + + (when noninteractive + (should-not (get-buffer "*ERC test warnings*")))) (defun erc-scenarios--common--sasl (mech) (erc-scenarios-common-with-cleanup diff --git a/test/lisp/erc/erc-scenarios-status-sidebar.el b/test/lisp/erc/erc-scenarios-status-sidebar.el index 3a047bf3983..b2b6351e333 100644 --- a/test/lisp/erc/erc-scenarios-status-sidebar.el +++ b/test/lisp/erc/erc-scenarios-status-sidebar.el @@ -64,8 +64,7 @@ erc-scenarios-status-sidebar--bufbar (let ((obuf (window-buffer))) ; *scratch* (set-window-buffer (selected-window) "#foo") (erc-d-t-wait-for 5 - (when noninteractive - (erc-status-sidebar-refresh)) + (erc-status-sidebar-refresh) (with-current-buffer "*ERC Status*" (and (marker-position erc-status-sidebar--active-marker) (goto-char erc-status-sidebar--active-marker) diff --git a/test/lisp/erc/resources/sasl/plain-failed.eld b/test/lisp/erc/resources/sasl/plain-failed.eld index 336700290c5..47d13de18e5 100644 --- a/test/lisp/erc/resources/sasl/plain-failed.eld +++ b/test/lisp/erc/resources/sasl/plain-failed.eld @@ -1,16 +1,16 @@ ;; -*- mode: lisp-data; -*- ((cap-req 10 "CAP REQ :sasl")) -((nick 1 "NICK tester")) -((user 1 "USER tester 0 * :tester") +((nick 10 "NICK tester")) +((user 10 "USER tester 0 * :tester") (0.0 ":irc.foonet.org NOTICE * :*** Looking up your hostname...") (0.0 ":irc.foonet.org NOTICE * :*** Found your hostname") (0.0 ":irc.foonet.org CAP * ACK :cap-notify sasl")) -((authenticate-plain 3.2 "AUTHENTICATE PLAIN") +((authenticate-plain 10 "AUTHENTICATE PLAIN") (0.0 ":irc.foonet.org AUTHENTICATE +")) -((authenticate-gimme 3.2 "AUTHENTICATE AHRlc3RlcgB3cm9uZw==") +((authenticate-gimme 10 "AUTHENTICATE AHRlc3RlcgB3cm9uZw==") (0.0 ":irc.foonet.org 900 * * tester :You are now logged in as tester") (0.0 ":irc.foonet.org 904 * :SASL authentication failed: Invalid account credentials")) -((cap-end 3.2 "CAP END")) +((eof 10 EOF)) commit 23d692ed0149e9cda327141082cafdba1e1266fe Author: F. Jason Park Date: Sun Dec 17 21:49:13 2023 -0800 Populate erc--msg-prop-overrides for CTCP replies * lisp/erc/erc-backend.el (erc-server-PRIVMSG): Don't set string intended for insertion to the undefined return value of `erc-process-ctcp-reply' and `erc-process-ctcp-query'. Rework control flow slightly for clarity. * lisp/erc/erc.el (erc-process-ctcp-reply): Bind `erc--msg-prop-overrides' and populate with `erc--ctcp' and `erc--cmd' "msg props" for the benefit of `erc-display-message' calls made by the various CTCP reply handlers. (Bug#67677) diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 0c336540483..6d30409e156 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -1996,8 +1996,8 @@ erc--speaker-status-prefix-wanted-p (erc--msg-prop-overrides `((erc--tmp) ,@erc--msg-prop-overrides)) (erc--speaker-status-prefix-wanted-p nil) (erc-current-message-catalog erc--message-speaker-catalog) - s buffer statusmsg cmem-prefix - fnick) + ;; + buffer statusmsg cmem-prefix fnick) (setq buffer (erc-get-buffer (if privp nick tgt) proc)) ;; Even worth checking for empty target here? (invalid anyway) (unless (or buffer noticep (string-empty-p tgt) (eq ?$ (aref tgt 0)) @@ -2042,36 +2042,31 @@ erc--speaker-status-prefix-wanted-p erc-show-speaker-membership-status inputp) (cdr cdata)))))) - (cond - ((erc-is-message-ctcp-p msg) - ;; FIXME explain undefined return values being assigned to `s'. - (setq s (if-let ((parsed - (erc--ctcp-response-from-parsed - :parsed parsed :buffer buffer :statusmsg statusmsg - :prefix cmem-prefix :dispname fnick)) - (msgp)) - (erc-process-ctcp-query proc parsed nick login host) - (erc-process-ctcp-reply proc parsed nick login host - (match-string 1 msg))))) - (t + (if (erc-is-message-ctcp-p msg) + (if noticep + (erc-process-ctcp-reply proc parsed nick login host + (match-string 1 msg)) + (setq parsed (erc--ctcp-response-from-parsed + :parsed parsed :buffer buffer :statusmsg statusmsg + :prefix cmem-prefix :dispname fnick)) + (erc-process-ctcp-query proc parsed nick login host)) (setq erc-server-last-peers (cons nick (cdr erc-server-last-peers))) (with-current-buffer (or buffer (current-buffer)) ;; Re-bind in case either buffer has a local value. - (let ((erc-current-message-catalog erc--message-speaker-catalog)) - (setq s (erc--determine-speaker-message-format-args - nick msg privp msgp inputp statusmsg - cmem-prefix fnick)))))) - (when s - (if (and noticep privp) - (progn - (push (cons 'erc--msg (car s)) erc--msg-prop-overrides) - (setq s (apply #'erc-format-message s)) - (run-hook-with-args 'erc-echo-notice-always-hook - s parsed buffer nick) - (run-hook-with-args-until-success - 'erc-echo-notice-hook s parsed buffer nick)) - (apply #'erc-display-message parsed nil buffer - (ensure-list s)))))))) + (let ((erc-current-message-catalog erc--message-speaker-catalog) + (msg-args (erc--determine-speaker-message-format-args + nick msg privp msgp inputp statusmsg + cmem-prefix fnick))) + (if (or msgp (not privp)) + ;; This is a PRIVMSG or a NOTICE to a channel. + (apply #'erc-display-message parsed nil buffer msg-args) + ;; This is a NOTICE directed at the client's current nick. + (push (cons 'erc--msg (car msg-args)) erc--msg-prop-overrides) + (let ((fmtmsg (apply #'erc-format-message msg-args))) + (run-hook-with-args 'erc-echo-notice-always-hook + fmtmsg parsed buffer nick) + (run-hook-with-args-until-success + 'erc-echo-notice-hook fmtmsg parsed buffer nick)))))))))) (define-erc-response-handler (QUIT) "Another user has quit IRC." nil diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 7071d8ca2d7..241e260e518 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -6528,8 +6528,14 @@ erc-ctcp-query-VERSION (defun erc-process-ctcp-reply (proc parsed nick login host msg) "Process MSG as a CTCP reply." (let* ((type (car (split-string msg))) - (hook (intern (concat "erc-ctcp-reply-" type "-hook")))) - (if (boundp hook) + (hook (intern-soft (concat "erc-ctcp-reply-" type "-hook"))) + ;; Help `erc-display-message' by ensuring subsequent + ;; insertions retain the necessary props. + (cmd (erc--get-eq-comparable-cmd (erc-response.command parsed))) + (erc--msg-prop-overrides `((erc--ctcp . ,(and hook (intern type))) + (erc--cmd . ,cmd) + ,@erc--msg-prop-overrides))) + (if (and hook (boundp hook)) (run-hook-with-args-until-success hook proc nick login host (car (erc-response.command-args parsed)) msg) commit 717f917d1de5272d6c24e8a32af1cc698989c41e Author: F. Jason Park Date: Mon Dec 18 19:38:30 2023 -0800 ; Fix some doc strings in ERC * lisp/erc/erc-networks.el: Lose some unneeded forward declarations. * lisp/erc/erc.el (erc-open-socks-tls-stream): Don't conflate SOCKS with TOR by mentioning a ".onion" address for the `host' parameter. * test/lisp/erc/erc-tests.el (erc--check-prompt-input-for-multiline-blanks): Extend timeout. diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el index 694f56ed0d5..590f1e88660 100644 --- a/lisp/erc/erc-networks.el +++ b/lisp/erc/erc-networks.el @@ -54,9 +54,7 @@ erc-server-process (declare-function erc-current-nick "erc" nil) (declare-function erc-display-error-notice "erc" (parsed string)) (declare-function erc-display-message "erc" (parsed type buffer msg &rest args)) -(declare-function erc-error "erc" (&rest args)) (declare-function erc-get-buffer "erc" (target &optional proc)) -(declare-function erc-server-buffer "erc" nil) (declare-function erc-server-process-alive "erc-backend" (&optional buffer)) (declare-function erc-set-active-buffer "erc" (buffer)) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index faa2cbefd1b..7071d8ca2d7 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -2852,12 +2852,15 @@ erc-open-tls-stream (defun erc-open-socks-tls-stream (name buffer host service &rest parameters) "Connect to an IRC server via SOCKS proxy over TLS. -Bind `erc-server-connect-function' to this function around calls -to `erc-tls'. See `erc-open-network-stream' for the meaning of -NAME and BUFFER. HOST should be a \".onion\" URL, SERVICE a TLS -port number, and PARAMETERS a sequence of key/value pairs, per -`open-network-stream'. See Info node `(erc) SOCKS' for more -info." +Defer to the `socks' and `gnutls' libraries to make the actual +connection and perform TLS negotiation. Expect SERVICE to be a +TLS port number and that the plist PARAMETERS contains a +`:client-certificate' pair when necessary. Otherwise, assume the +arguments NAME, BUFFER, and HOST to be acceptable to +`open-network-stream' and that users know to check out +`erc-server-connect-function' and Info node `(erc) SOCKS' for +more info, including an important example of how to \"wrap\" this +function with SOCKS credentials." (require 'gnutls) (require 'socks) (let ((proc (socks-open-network-stream name buffer host service)) diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 45cf4ea489f..8a28d351b0f 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -1520,7 +1520,7 @@ erc-tests--check-prompt-input-messages (ert-deftest erc--check-prompt-input-for-multiline-blanks () (erc-tests--with-process-input-spy (lambda (next) - (erc-tests--set-fake-server-process "sleep" "1") + (erc-tests--set-fake-server-process "sleep" "10") (should-not erc-send-whitespace-lines) (should erc-warn-about-blank-lines) commit 13182ae976859114601c12abff27378a31db3c2f Author: Po Lu Date: Sat Dec 23 20:50:16 2023 +0800 ; * src/xdisp.c (draw_glyphs): Fix coding style. diff --git a/src/xdisp.c b/src/xdisp.c index 0a1fef9b81c..2a979c5cb9e 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -30955,7 +30955,7 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row, ptrdiff_t id; id = lookup_image (f, s->img->spec, hlinfo->mouse_face_face_id); s->img = IMAGE_FROM_ID (f, id); - prepare_image_for_display(f, s->img); + prepare_image_for_display (f, s->img); } } #endif commit 1be62044732df0c4f1be9679a4ada09850a9e2ab Merge: b09765a7114 a4751657389 Author: Eli Zaretskii Date: Sat Dec 23 06:30:40 2023 -0500 Merge from origin/emacs-29 a4751657389 * doc/man/emacsclient.1: Fix --tramp option. 1e5357d3d1f * doc/man/emacsclient.1: Add missing sections (bug#66598) fba7b9db397 Add explanation for extra parentheses in ELisp Introduction 77232826821 Add sample code to the "let*" section in "forward-paragraph" 7a00ca92c19 Fix treesit test (bug#67117) d220893216c Fix c++-ts-mode indentation (bug#67975) d386a8aa43f Recommend customizing eglot for python-base-mode bd0c7589715 Improve documentation of new native-compilation commands 1ad126c0f28 ; Fix typo 77678244b83 doc/lispintro: Don't mention `set` (bug#67734) cb3684e9dfa Fix script for some characters 2922d683b78 ; * src/treesit.c (treesit_traverse_child_helper): Fix co... 7b315e8a5c9 Fix an issue when searching subtree backward (bug#67117) 03625c2fefa Fix passive mode for tnftp client in ange-ftp.el. b6429b1c1c7 ; Improve documentation of ispell.el's dictionary database 75cc1593412 ; * etc/PROBLEMS: Update the "GnuPG hangs" entry. 67d9af1c074 Fix using disabled command without a docstring f68f3500236 Improve documentation of text properties handling when ya... 06c399914fa Eglot: Add Uiua language server commit a4751657389cf47c18416fa5d148ad2a67e14565 Author: Michael Albinus Date: Sat Dec 23 12:04:37 2023 +0100 * doc/man/emacsclient.1: Fix --tramp option. diff --git a/doc/man/emacsclient.1 b/doc/man/emacsclient.1 index b04923262de..75f38e4e50e 100644 --- a/doc/man/emacsclient.1 +++ b/doc/man/emacsclient.1 @@ -1,5 +1,5 @@ .\" See section COPYING for conditions for redistribution. -.TH EMACSCLIENT 1 "2023-10-25" "GNU Emacs" "GNU" +.TH EMACSCLIENT 1 "2023-12-23" "GNU Emacs" "GNU" .\" NAME should be all caps, SECTION should be 1-8, maybe w/ subsection .\" other params are allowed: see man(7), man(1) .SH NAME @@ -158,7 +158,7 @@ option, if present. .B EMACSCLIENT_TRAMP A prefix to add to filenames, intended to allow Emacs to locate files on remote machines using TRAMP. Will be overridden by the -.B \-\-tramp-prefix +.B \-\-tramp option, if present. .TP .B EMACS_SERVER_FILE commit b09765a7114a92fbb71dad50a44a66938723624d Author: Eli Zaretskii Date: Sat Dec 23 13:03:09 2023 +0200 Fix alignment of columns in Dired display with ls-lisp * lisp/dired.el (dired-align-file): Don't realign the first column of file's data. (Bug#67953) diff --git a/lisp/dired.el b/lisp/dired.el index 357787b6495..5239e568de1 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -1613,14 +1613,21 @@ dired-align-file ;; the beginning or the end of the next field, depending on ;; whether this field is left or right aligned). (align-pt-offset - (save-excursion - (goto-char other) - (move-to-column curcol) - (when (looking-at - (concat - (if (eq (char-before) ?\s) " *" "[^ ]* *") - (if num-align "[0-9][^ ]*"))) - (- (match-end 0) (match-beginning 0))))) + ;; It is never TRT to realign the first column of + ;; file's data. But the code below does attempt to + ;; realign the first column if there's no whitespace + ;; before it, so we force it to let the first column + ;; alone. + (if (zerop curcol) + 0 + (save-excursion + (goto-char other) + (move-to-column curcol) + (when (looking-at + (concat + (if (eq (char-before) ?\s) " *" "[^ ]* *") + (if num-align "[0-9][^ ]*"))) + (- (match-end 0) (match-beginning 0)))))) ;; Now, the number of spaces to insert is align-pt-offset ;; minus the distance to the equivalent point on the ;; current line. commit 44be4e92eca68ec4498c424573f0505aca69d39c Author: Eli Zaretskii Date: Sat Dec 23 12:46:55 2023 +0200 ; Improve and correct documentation of registers (bug#66394) Suggested by Thierry Volpiatto . * doc/emacs/regs.texi (Registers): Mention filtering of registers in the preview. * lisp/register.el (register-use-preview) (register--preview-function, register-preview-info): Doc fixes. diff --git a/doc/emacs/regs.texi b/doc/emacs/regs.texi index d7542e996dc..988e606741f 100644 --- a/doc/emacs/regs.texi +++ b/doc/emacs/regs.texi @@ -65,9 +65,16 @@ Registers existing registers in this mode, you need to type @key{RET} after selecting the register by navigation or typing its name. +In addition, the registers shown by the preview are filtered according +to the command that popped the preview: for example, the preview shown +by @code{insert-register} will only show registers whose values can be +inserted into the buffer, omitting registers which hold window +configurations, positions, and other un-insertable values. + @item nil This value requests behavior similar to @code{traditional}, but the -preview is shown without delay. +preview is shown without delay, and is filtered according to the +command. @item never This value is like @code{nil}, but it disables the preview. diff --git a/lisp/register.el b/lisp/register.el index bd8e8c2edcd..d1d55dff660 100644 --- a/lisp/register.el +++ b/lisp/register.el @@ -138,10 +138,7 @@ register-use-preview all; the preview buffer is still accessible with `help-char' (C-h). When set to \\='traditional (the default), provide a more basic preview according to `register-preview-delay'; this preserves the traditional -behavior of Emacs 29 and before. - -This has no effect when the value of `register--read-with-preview-function' -is `register-read-with-preview-traditional'." +behavior of Emacs 29 and before." :type '(choice (const :tag "Use preview" t) (const :tag "Use quick preview" nil) @@ -192,8 +189,7 @@ register-preview-default (register-describe-oneline (car r)))) (cl-defgeneric register--preview-function (read-preview-function) - "Return a function to format a register for previewing. -This is according to the value of `read-preview-function'.") + "Return a function to format registers for previewing by READ-PREVIEW-FUNCTION.") (cl-defmethod register--preview-function ((_read-preview-function (eql register-read-with-preview-traditional))) #'register-preview-default) @@ -207,7 +203,8 @@ register-preview-info MSG is the minibuffer message to show when a register is selected. ACT is the type of action the command is doing on register. SMATCH accept a boolean value to say if the command accepts non-matching -registers." +registers. +If NOCONFIRM is non-nil, request confirmation of register name by RET." types msg act smatch noconfirm) (cl-defgeneric register-command-info (command) commit e69fafdbc8893a0456535605082c7d7c469fdabd Author: Manuel Giraud Date: Tue Dec 19 12:25:24 2023 +0100 Respect mouse-face on SVG image glyphs (bug#67794) * src/dispextern.h: * src/image.c (image_spec_value): Export 'image_spec_value'. * src/xdisp.c (draw_glyphs): Maybe update SVG image glyphs with mouse face features before drawing. diff --git a/src/dispextern.h b/src/dispextern.h index 3a4d6095f73..020c33a2628 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3618,6 +3618,7 @@ #define TRY_WINDOW_IGNORE_FONTS_CHANGE (1 << 1) bool valid_image_p (Lisp_Object); void prepare_image_for_display (struct frame *, struct image *); ptrdiff_t lookup_image (struct frame *, Lisp_Object, int); +Lisp_Object image_spec_value (Lisp_Object, Lisp_Object, bool *); #if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_NS \ || defined HAVE_HAIKU || defined HAVE_ANDROID diff --git a/src/image.c b/src/image.c index 38744fc1cce..651ec0b34e5 100644 --- a/src/image.c +++ b/src/image.c @@ -1543,7 +1543,7 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords, if KEY is not present in SPEC. Set *FOUND depending on whether KEY was found in SPEC. */ -static Lisp_Object +Lisp_Object image_spec_value (Lisp_Object spec, Lisp_Object key, bool *found) { Lisp_Object tail; diff --git a/src/xdisp.c b/src/xdisp.c index 1f571a2b221..0a1fef9b81c 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -30940,6 +30940,26 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row, } } +#ifdef HAVE_RSVG + /* Update SVG image glyphs with mouse face features. FIXME: it + should be possible to have this behaviour with transparent + background PNG. */ + if (hl == DRAW_MOUSE_FACE) + { + Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); + for (s = head; s; s = s->next) + if (s->first_glyph->type == IMAGE_GLYPH) + if (s->img + && (EQ (image_spec_value (s->img->spec, QCtype, NULL), Qsvg))) + { + ptrdiff_t id; + id = lookup_image (f, s->img->spec, hlinfo->mouse_face_face_id); + s->img = IMAGE_FROM_ID (f, id); + prepare_image_for_display(f, s->img); + } + } +#endif + /* Draw all strings. */ for (s = head; s; s = s->next) FRAME_RIF (f)->draw_glyph_string (s); commit 1e5357d3d1f5ecf68f1f34d017954d591eaaed14 Author: Peter Oliver Date: Sat Oct 21 14:02:06 2023 +0100 * doc/man/emacsclient.1: Add missing sections (bug#66598) Copyright-paperwork-exempt: yes diff --git a/doc/man/emacsclient.1 b/doc/man/emacsclient.1 index 0acf3dd339e..b04923262de 100644 --- a/doc/man/emacsclient.1 +++ b/doc/man/emacsclient.1 @@ -62,9 +62,11 @@ This option applies only to the next file specified. .TP .B \-a, \-\-alternate-editor=COMMAND If the Emacs server is not running, run the specified shell command instead. -This can also be specified via the ALTERNATE_EDITOR environment variable. -If the value of ALTERNATE_EDITOR is the empty string, run "emacs \-\-daemon" to +If the empty string is specified, run "emacs \-\-daemon" to start Emacs in daemon mode, and try to connect to it. + +See also the ALTERNATE_EDITOR environment variable, over which this +option takes precedence. .TP .B -c, \-\-create-frame Create a new frame instead of trying to use the current Emacs frame. @@ -84,7 +86,11 @@ Lisp expressions. .TP .B \-f, \-\-server-file=FILENAME Use TCP configuration file FILENAME for communication. -This can also be specified via the EMACS_SERVER_FILE environment variable. +Relative filenames are relative to "~/.emacs.d/server/" or +"$XDG_CONFIG_HOME/emacs/server/", and the default is "server". + +See also the EMACS_SERVER_FILE environment variable, over which this +option takes precedence. .TP .B \-n, \-\-no-wait Return immediately without waiting for you to "finish" the buffer in @@ -114,7 +120,10 @@ side-effect rather than result. .TP .B \-s, \-\-socket-name=FILENAME Use socket named FILENAME for communication. -This can also be specified via the EMACS_SOCKET_NAME environment variable. +Relative filenames are relative to "$XDG_RUNTIME_DIR/emacs/" or "$TMPDIR/". + +See also the EMACS_SOCKET_NAME environment variable, over which this +option takes precedence. .TP .B \-nw, \-t, \-\-tty Open a new Emacs frame on the current terminal. @@ -122,8 +131,11 @@ Open a new Emacs frame on the current terminal. .B \-T, \-\-tramp=PREFIX Set PREFIX to add to filenames for Emacs to locate files on remote machines using TRAMP. This is mostly useful in combination with using -the Emacs server over TCP with --server-file. This can also be -specified via the EMACSCLIENT_TRAMP environment variable. +the Emacs server on a remote host (either using TCP with +--server-file, or a socket forwarded over SSH). + +See also the EMACSCLIENT_TRAMP environment variable, over which this +option takes precedence. .TP .B \-V, \-\-version Print version information and exit. @@ -133,10 +145,46 @@ Print this usage information message and exit. .SH "EXIT STATUS" Normally, the exit status is 0. If emacsclient shuts down due to Emacs signaling an error, the exit status is 1. +.SH ENVIRONMENT +.TP +.B ALTERNATE_EDITOR +If the Emacs server is not running, run the shell command in this +environment variable instead. If set to the empty string, run +"emacs \-\-daemon" to start Emacs in daemon mode, and try to connect +to it. Will be overridden by the +.B \-\-alternate-editor +option, if present. +.TP +.B EMACSCLIENT_TRAMP +A prefix to add to filenames, intended to allow Emacs to locate files +on remote machines using TRAMP. Will be overridden by the +.B \-\-tramp-prefix +option, if present. +.TP +.B EMACS_SERVER_FILE +Look in this file to discover where to find a TCP Emacs server. +Relative filenames are relative to "~/.emacs.d/server/" or +"$XDG_CONFIG_HOME/emacs/server/", and the +default is "server". Will be overridden by the +.B \-\-server-file +option, if present. +.TP +.B EMACS_SOCKET_NAME +The filename of the socket to use for communication with the Emacs server. +Relative filenames are relative to "$XDG_RUNTIME_DIR/emacs/" or "$TMPDIR/". +Will be overridden by the +.B \-\-socket-name +option, if present. .SH "SEE ALSO" The program is documented fully in .IR "Using Emacs as a Server" available via the Info system. + +The XDG_ environment variables are described in detail in the +.UR https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html +XDG Base Directory Specification +.UE . + .SH AUTHOR This manual page was originally written by Stephane Bortzmeyer , for the Debian GNU/Linux system, but is not commit fba7b9db39771edbbc71a8122c7b0ea1ce24ec96 Author: Xiyue Deng Date: Wed Dec 13 16:21:10 2023 -0800 Add explanation for extra parentheses in ELisp Introduction * doc/lispintro/emacs-lisp-intro.texi (fwd-para while): Add a note to explain the extra parentheses. (Bug#67820) diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index aaa7511ef30..4a0e8dfa1fc 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -13248,6 +13248,10 @@ fwd-para while @end smallexample @noindent +(Note that this code snippet is copied verbatim from the original code, +so the two extra ending parentheses are matching the previous @code{if} +and @code{while}.) + This says that if there is no fill prefix and if we are not at the end, point should move to the beginning of whatever was found by the regular expression search for @code{sp-parstart}. commit cbbb19ced674dc8c42c95238577abb9849a75b87 Author: Visuwesh Date: Tue Dec 12 21:14:12 2023 +0530 Make ffap correctly guess remote file names at point * lisp/ffap.el (ffap-lax-url): Set it to nil so that remote file names may be matched. (ffap-fixup-email): New function. (ffap-guesser): Specially handle email addresses now that 'ffap-lax-url' is nil, as user@host fails to be matched as an email address with that setting. (Bug#67688) * etc/NEWS: Announce the new value of the defcustom. diff --git a/etc/NEWS b/etc/NEWS index 03218d08d80..6df17aa3f0a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -278,6 +278,11 @@ elaborate and error-prone escaping (to protect them from the shell). When answering the prompt with "diff" or "=", it now shows the diffs between the auto save file and the current file. +--- +** 'ffap-lax-url' now defaults to nil. +Previously, it was set to 'ffap-lax-url' to t but this broke remote file +name detection. + * Editing Changes in Emacs 30.1 diff --git a/lisp/ffap.el b/lisp/ffap.el index 530e3da182e..9cea11cf540 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el @@ -152,15 +152,15 @@ ffap-url-unwrap-remote :group 'ffap :version "24.3") -(defcustom ffap-lax-url t +(defcustom ffap-lax-url nil "If non-nil, allow lax URL matching. The default non-nil value might produce false URLs in C++ code with symbols like \"std::find\". On the other hand, setting this to nil will disable recognition of URLs that are not -well-formed, such as \"user@host\" or \"\"." +well-formed." :type 'boolean :group 'ffap - :version "25.2") ; nil -> t + :version "30.1") (defcustom ffap-ftp-default-user "anonymous" "User name in FTP file names generated by `ffap-host-to-filename'. @@ -609,6 +609,13 @@ ffap-fixup-url ((and ffap-url-unwrap-remote (ffap-url-unwrap-remote url))) (url))) +(defun ffap-fixup-email (email) + "Clean up EMAIL and return it as a mailto: URL." + (when (stringp email) + (if (string-prefix-p "mailto:" email) + email + (concat "mailto:" email)))) + ;;; File Name Handling: @@ -1571,6 +1578,7 @@ ffap-guesser (ffap-fixup-url (or (ffap-url-at-point) (ffap-gopher-at-point)))) (ffap-file-at-point) ; may yield url! + (ffap-fixup-email (thing-at-point 'email)) (ffap-fixup-machine (ffap-machine-at-point)))) (defun ffap-prompter (&optional guess suffix) commit e54e25129ec631969e1febdcf44d2f99a1791063 Author: Gerd Möllmann Date: Sat Dec 23 10:04:09 2023 +0100 ; Add autoload cookie for tags-reset-tags-tables diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el index d48dcc6659d..a14bf0176fd 100644 --- a/lisp/progmodes/etags.el +++ b/lisp/progmodes/etags.el @@ -732,6 +732,7 @@ visit-tags-table-buffer "File %s does not exist") local-tags-file-name))))) +;;;###autoload (defun tags-reset-tags-tables () "Reset tags state to cancel effect of any previous \\[visit-tags-table] or \\[find-tag]." (interactive) commit 77232826821a60b50ab2c1f315ebffd4ebecfe66 Author: Xiyue Deng Date: Wed Dec 13 13:38:55 2023 -0800 Add sample code to the "let*" section in "forward-paragraph" * doc/lispintro/emacs-lisp-intro.texi (fwd-para let): Add code sample. (Bug#67817) diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index 68943d9b6f4..aaa7511ef30 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -12847,7 +12847,40 @@ fwd-para let introduced}), in which Emacs binds a total of seven variables: @code{opoint}, @code{fill-prefix-regexp}, @code{parstart}, @code{parsep}, @code{sp-parstart}, @code{start}, and -@code{found-start}. +@code{found-start}. The first part of the @code{let*} expression +looks like below: + +@smallexample +@group +(let* ((opoint (point)) + (fill-prefix-regexp + (and fill-prefix (not (equal fill-prefix "")) + (not paragraph-ignore-fill-prefix) + (regexp-quote fill-prefix))) + ;; Remove ^ from paragraph-start and paragraph-sep if they are there. + ;; These regexps shouldn't be anchored, because we look for them + ;; starting at the left-margin. This allows paragraph commands to + ;; work normally with indented text. + ;; This hack will not find problem cases like "whatever\\|^something". + (parstart (if (and (not (equal "" paragraph-start)) + (equal ?^ (aref paragraph-start 0))) + (substring paragraph-start 1) + paragraph-start)) + (parsep (if (and (not (equal "" paragraph-separate)) + (equal ?^ (aref paragraph-separate 0))) + (substring paragraph-separate 1) + paragraph-separate)) + (parsep + (if fill-prefix-regexp + (concat parsep "\\|" + fill-prefix-regexp "[ \t]*$") + parsep)) + ;; This is used for searching. + (sp-parstart (concat "^[ \t]*\\(?:" parstart "\\|" parsep "\\)")) + start found-start) + ...) +@end group +@end smallexample The variable @code{parsep} appears twice, first, to remove instances of @samp{^}, and second, to handle fill prefixes. commit 7a00ca92c191a8d105283f73e9b68f6a0378a3a0 Author: Denis Zubarev Date: Sun Nov 12 01:42:42 2023 +0300 Fix treesit test (bug#67117) * test/src/treesit-tests.el (treesit-search-subtree-forward-1): (treesit-search-subtree-backward-1): Replace treesit--thing-at with treesit-query-capture (treesit--thing-at isn't available in Emacs 29). diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el index 9ba3a9340c1..1763c3894f5 100644 --- a/test/src/treesit-tests.el +++ b/test/src/treesit-tests.el @@ -1090,9 +1090,12 @@ treesit-search-subtree-forward-1 (python-ts-mode) (insert "Temp(1, 2)") (goto-char (point-min)) - (let ((node (treesit-search-subtree - (treesit--thing-at (point) "call") - (lambda (n) (equal (treesit-node-type n ) "integer"))))) + (pcase-let* ((`((,_ . ,call-node)) + (treesit-query-capture (treesit-buffer-root-node) + '((call) @c))) + (node (treesit-search-subtree + call-node + (lambda (n) (equal (treesit-node-type n) "integer"))))) (should node) (should (equal (treesit-node-text node) "1")))) @@ -1104,10 +1107,13 @@ treesit-search-subtree-backward-1 (python-ts-mode) (insert "Temp(1, 2)") (goto-char (point-min)) - (let ((node (treesit-search-subtree - (treesit--thing-at (point) "call") - (lambda (n) (equal (treesit-node-type n ) "integer")) - t))) + (pcase-let* ((`((,_ . ,call-node)) + (treesit-query-capture (treesit-buffer-root-node) + '((call) @c))) + (node (treesit-search-subtree + call-node + (lambda (n) (equal (treesit-node-type n) "integer")) + t))) (should node) (should (equal (treesit-node-text node) "2")))) commit d220893216c3c6873b2bb529628e08c526d7f4ff Author: Yuan Fu Date: Fri Dec 22 21:25:00 2023 -0800 Fix c++-ts-mode indentation (bug#67975) * lisp/progmodes/c-ts-mode.el (c-ts-mode--indent-styles): Make indent rule match precise so it doesn't match declaration_list. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index ca831a9c5f9..d069ddefa6a 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -437,7 +437,7 @@ c-ts-mode--indent-styles ((parent-is "function_definition") parent-bol 0) ((parent-is "pointer_declarator") parent-bol 0) - ((parent-is "declaration") parent-bol 0) + ((parent-is ,(rx bos "declaration" eos)) parent-bol 0) ((parent-is "conditional_expression") first-sibling 0) ((parent-is "assignment_expression") parent-bol c-ts-mode-indent-offset) ((parent-is "concatenated_string") first-sibling 0) commit d386a8aa43f77f9317db6f52ef70f43a48237f99 Author: Stefan Kangas Date: Fri Dec 22 22:36:37 2023 +0100 Recommend customizing eglot for python-base-mode * doc/misc/eglot.texi (Project-specific configuration): Recommend setting directory local variables for 'python-base-mode' instead of 'python-mode'. This makes any customizations effective also for 'python-ts-mode'. diff --git a/doc/misc/eglot.texi b/doc/misc/eglot.texi index f7543193f18..bbf323a873f 100644 --- a/doc/misc/eglot.texi +++ b/doc/misc/eglot.texi @@ -1085,8 +1085,8 @@ Project-specific configuration :fuzzy t) :pylint (:enabled :json-false))) :gopls (:usePlaceholders t))))) - (python-mode . ((indent-tabs-mode . nil))) - (go-mode . ((indent-tabs-mode . t)))) + (python-base-mode . ((indent-tabs-mode . nil))) + (go-mode . ((indent-tabs-mode . t)))) @end lisp @noindent @@ -1101,7 +1101,7 @@ Project-specific configuration This following form may also be used: @lisp -((python-mode +((python-base-mode . ((eglot-workspace-configuration . (:pylsp (:plugins (:jedi_completion (:include_params t :fuzzy t) @@ -1116,7 +1116,7 @@ Project-specific configuration @noindent This sets up the value of @code{eglot-workspace-configuration} separately depending on the major mode of each of that project's -buffers. @code{python-mode} buffers will have the variable set to +buffers. @code{python-base-mode} buffers will have the variable set to @code{(:pylsp (:plugins ...))}. @code{go-mode} buffers will have the variable set to @code{(:gopls (:usePlaceholders t))}. @@ -1127,7 +1127,7 @@ Project-specific configuration may use something like: @lisp -((python-mode +((python-base-mode . ((eglot-workspace-configuration . (:pylsp (:plugins (:jedi_completion (:include_params t :fuzzy t) commit bd0c75897153ea5ce1e4ba12c81c3b280a0b95e4 Author: Eli Zaretskii Date: Fri Dec 22 16:49:49 2023 +0200 Improve documentation of new native-compilation commands * lisp/progmodes/elisp-mode.el (emacs-lisp-mode-menu) (emacs-lisp-native-compile, emacs-lisp-native-compile-and-load): Doc fixes. * doc/lispref/compile.texi (Native-Compilation Functions): Document 'emacs-lisp-native-compile' and 'emacs-lisp-native-compile-and-load'. diff --git a/doc/lispref/compile.texi b/doc/lispref/compile.texi index 96d66445360..3a6a3733055 100644 --- a/doc/lispref/compile.texi +++ b/doc/lispref/compile.texi @@ -878,8 +878,7 @@ Native-Compilation Functions You can natively-compile either a single function or macro definition, or a whole file of Lisp code, with the @code{native-compile} function. Natively-compiling a file will -produce both the corresponding @file{.elc} file with byte code and the -@file{.eln} file with native code. +produce the @file{.eln} file with native code. @findex native-comp-limple-mode @vindex native-comp-verbose @@ -971,6 +970,18 @@ Native-Compilation Functions Variables}). @end defun +@deffn Command emacs-lisp-native-compile +This command compiles the file visited by the current buffer into +native code, if the file was changed since the last time it was +natively-compiled. +@end deffn + +@deffn Command emacs-lisp-native-compile-and-load +This command compiles the file visited by the current buffer into +native code, like @code{emacs-lisp-native-compile}, but it also loads +the native code when the compilation finishes. +@end deffn + The following function allows Lisp programs to test whether native-compilation is available at runtime. diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 354d98c50dc..105b017c215 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -85,10 +85,10 @@ emacs-lisp-mode-menu ["Byte-recompile Directory..." byte-recompile-directory :help "Recompile every `.el' file in DIRECTORY that needs recompilation"] ["Native-compile This File" emacs-lisp-native-compile - :help "Compile the current file containing the current buffer to native code" + :help "Compile this buffer's file to native code" :active (native-comp-available-p)] ["Native-compile and Load" emacs-lisp-native-compile-and-load - :help "Compile the current file to native code, then load compiled native code" + :help "Compile this buffer's file to native code, then load compiled native code" :active (native-comp-available-p)] ["Disassemble Byte Compiled Object..." disassemble :help "Print disassembled code for OBJECT in a buffer"] @@ -224,7 +224,9 @@ emacs-lisp-byte-compile-and-load (declare-function comp-write-bytecode-file "comp") (defun emacs-lisp-native-compile () - "Native-compile synchronously the current file (if it has changed)." + "Native-compile the current buffer's file (if it has changed). +This invokes a synchronous native-compilation of the file that is +visited by the current buffer." (interactive nil emacs-lisp-mode) (emacs-lisp--before-compile-buffer) (let* ((byte+native-compile t) @@ -234,12 +236,14 @@ emacs-lisp-native-compile (comp-write-bytecode-file eln)))) (defun emacs-lisp-native-compile-and-load () - "Native-compile synchronously the current file (if it has changed). -Load the compiled code when finished. + "Native-compile the current buffer's file (if it has changed), then load it. +This invokes a synchronous native-compilation of the file that is +visited by the current buffer, then loads the compiled native code +when the compilation is finished. Use `emacs-lisp-byte-compile-and-load' in combination with `native-comp-jit-compilation' set to t to achieve asynchronous -native compilation." +native compilation of the current buffer's file." (interactive nil emacs-lisp-mode) (when-let ((byte-file (emacs-lisp-native-compile))) (load (file-name-sans-extension byte-file)))) commit 1ad126c0f28aae2b5d2da9b347a33e4300424de9 Author: Stefan Kangas Date: Fri Dec 22 11:45:23 2023 +0100 ; Fix typo diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index 6b048a8a805..be3bdda1d13 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -583,7 +583,7 @@ ispell-dictionary-alist OTHERCHARS slots of the alist should contain the same character set as casechars and otherchars in the LANGUAGE.aff file \(e.g., english.aff). Aspell and Hunspell don't have this limitation. -Allso, when the speller program is \"aspell\" or \"hunspell\", +Also, when the speller program is \"aspell\" or \"hunspell\", some parts of the database, notably OTHERCHARS, will be determined by parsing the dictionary data files, see `ispell-aspell-find-dictionary' and `ispell-parse-hunspell-affix-file'.") commit 77678244b83455b34a92e90ddeea4c68799d1d58 Author: Stefan Monnier Date: Thu Dec 21 10:24:29 2023 -0500 doc/lispintro: Don't mention `set` (bug#67734) * doc/lispintro/emacs-lisp-intro.texi (Using set): Delete. (Using setq): Adjust accordingly. (setq): Rename from "set & setq" and don't refer to `set` any more. (Review): Don't mention `set` any more. diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index eb8ff413b79..68943d9b6f4 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -317,7 +317,7 @@ Top * Evaluation:: Running a program. * Variables:: Returning a value from a variable. * Arguments:: Passing information to a function. -* set & setq:: Setting the value of a variable. +* setq:: Setting the value of a variable. * Summary:: The major points. * Error Message Exercises:: @@ -358,7 +358,6 @@ Top Setting the Value of a Variable -* Using set:: Setting values. * Using setq:: Setting a quoted value. * Counting:: Using @code{setq} to count. @@ -1060,7 +1059,7 @@ List Processing * Evaluation:: Running a program. * Variables:: Returning a value from a variable. * Arguments:: Passing information to a function. -* set & setq:: Setting the value of a variable. +* setq:: Setting the value of a variable. * Summary:: The major points. * Error Message Exercises:: @end menu @@ -1782,7 +1781,7 @@ fill-column Example string, @code{"such as this"}; to a list, such as @code{(spruce pine oak)}; we can even bind a variable to a function definition. -A symbol can be bound to a value in several ways. @xref{set & setq, , +A symbol can be bound to a value in several ways. @xref{setq, , Setting the Value of a Variable}, for information about one way to do this. @@ -2273,52 +2272,52 @@ message message @code{"He saw 38 red foxes leaping."} appears in your echo area. -@node set & setq +@node setq @section Setting the Value of a Variable @cindex Variable, setting value @cindex Setting value of variable @cindex @samp{bind} defined -There are several ways by which a variable can be given a value. One of -the ways is to use either the function @code{set} or the special form -@code{setq}. Another way is to use @code{let} (@pxref{let}). (The -jargon for this process is to @dfn{bind} a variable to a value.) +There are several ways by which a variable can be given a value. +One of the ways is to use the special form @code{setq}. Another way +is to use @code{let} (@pxref{let}). (The jargon for this process is +to @dfn{bind} a variable to a value.) -The following sections not only describe how @code{set} and @code{setq} -work but also illustrate how arguments are passed. +The following sections not only describe how @code{setq} works but +also illustrate how arguments are passed. @menu -* Using set:: Setting values. -* Using setq:: Setting a quoted value. +* Using setq:: Setting variables. * Counting:: Using @code{setq} to count. @end menu -@node Using set -@subsection Using @code{set} +@node Using setq +@subsection Using @code{setq} @findex set -To set the value of the symbol @code{flowers} to the list @code{'(rose +To set the value of the symbol @code{flowers} to the list @code{(rose violet daisy buttercup)}, evaluate the following expression by positioning the cursor after the expression and typing @kbd{C-x C-e}. @smallexample -(set 'flowers '(rose violet daisy buttercup)) +(setq flowers '(rose violet daisy buttercup)) @end smallexample @noindent The list @code{(rose violet daisy buttercup)} will appear in the echo -area. This is what is @emph{returned} by the @code{set} function. As a -side effect, the symbol @code{flowers} is bound to the list; that is, -the symbol @code{flowers}, which can be viewed as a variable, is given -the list as its value. (This process, by the way, illustrates how a -side effect to the Lisp interpreter, setting the value, can be the -primary effect that we humans are interested in. This is because every -Lisp function must return a value if it does not get an error, but it -will only have a side effect if it is designed to have one.) +area. This is what is @emph{returned} by the @code{setq} special +form. As a side effect, the symbol @code{flowers} is bound to the +list; that is, the symbol @code{flowers}, which can be viewed as +a variable, is given the list as its value. (This process, by the +way, illustrates how a side effect to the Lisp interpreter, setting +the value, can be the primary effect that we humans are interested in. +This is because every Lisp function must return a value if it does not +get an error, but it will only have a side effect if it is designed to +have one.) -After evaluating the @code{set} expression, you can evaluate the symbol -@code{flowers} and it will return the value you just set. Here is the -symbol. Place your cursor after it and type @kbd{C-x C-e}. +After evaluating the @code{setq} expression, you can evaluate the +symbol @code{flowers} and it will return the value you just set. +Here is the symbol. Place your cursor after it and type @kbd{C-x C-e}. @smallexample flowers @@ -2336,30 +2335,8 @@ Using set 'flowers @end smallexample -Note also, that when you use @code{set}, you need to quote both -arguments to @code{set}, unless you want them evaluated. Since we do -not want either argument evaluated, neither the variable -@code{flowers} nor the list @code{(rose violet daisy buttercup)}, both -are quoted. (When you use @code{set} without quoting its first -argument, the first argument is evaluated before anything else is -done. If you did this and @code{flowers} did not have a value -already, you would get an error message that the @samp{Symbol's value -as variable is void}; on the other hand, if @code{flowers} did return -a value after it was evaluated, the @code{set} would attempt to set -the value that was returned. There are situations where this is the -right thing for the function to do; but such situations are rare.) - -@node Using setq -@subsection Using @code{setq} -@findex setq - -As a practical matter, you almost always quote the first argument to -@code{set}. The combination of @code{set} and a quoted first argument -is so common that it has its own name: the special form @code{setq}. -This special form is just like @code{set} except that the first argument -is quoted automatically, so you don't need to type the quote mark -yourself. Also, as an added convenience, @code{setq} permits you to set -several different variables to different values, all in one expression. +Also, as an added convenience, @code{setq} permits you to set several +different variables to different values, all in one expression. To set the value of the variable @code{carnivores} to the list @code{'(lion tiger leopard)} using @code{setq}, the following expression @@ -2369,18 +2346,6 @@ Using setq (setq carnivores '(lion tiger leopard)) @end smallexample -@noindent -This is exactly the same as using @code{set} except the first argument -is automatically quoted by @code{setq}. (The @samp{q} in @code{setq} -means @code{quote}.) - -@need 1250 -With @code{set}, the expression would look like this: - -@smallexample -(set 'carnivores '(lion tiger leopard)) -@end smallexample - Also, @code{setq} can be used to assign different values to different variables. The first argument is bound to the value of the second argument, the third argument is bound to the value of the @@ -2400,14 +2365,14 @@ Using setq not have fit on a page; and humans find it easier to read nicely formatted lists.) -Although I have been using the term ``assign'', there is another way of -thinking about the workings of @code{set} and @code{setq}; and that is to -say that @code{set} and @code{setq} make the symbol @emph{point} to the -list. This latter way of thinking is very common and in forthcoming -chapters we shall come upon at least one symbol that has ``pointer'' as -part of its name. The name is chosen because the symbol has a value, -specifically a list, attached to it; or, expressed another way, -the symbol is set to point to the list. +Although I have been using the term ``assign'', there is another way +of thinking about the workings of @code{setq}; and that is to say that +@code{setq} makes the symbol @emph{point} to the list. This latter +way of thinking is very common and in forthcoming chapters we shall +come upon at least one symbol that has ``pointer'' as part of its +name. The name is chosen because the symbol has a value, specifically +a list, attached to it; or, expressed another way, the symbol is set +to point to the list. @node Counting @subsection Counting @@ -3598,6 +3563,8 @@ Prevent confusion @unnumberedsubsec @code{let} Prevents Confusion @end ifnottex +@c FIXME!! lexbind!! + @cindex @samp{local variable} defined @cindex @samp{variable, local}, defined The @code{let} special form prevents confusion. @code{let} creates a @@ -4471,9 +4438,7 @@ Review The @code{setq} special form sets the value of its first argument to the value of the second argument. The first argument is automatically quoted by @code{setq}. It does the same for succeeding pairs of -arguments. Another function, @code{set}, takes only two arguments and -evaluates both of them before setting the value returned by its first -argument to the value returned by its second argument. +arguments. @item buffer-name Without an argument, return the name of the buffer, as a string. @@ -16949,15 +16914,15 @@ Text and Auto-fill @noindent This line is a short, but complete Emacs Lisp expression. -We are already familiar with @code{setq}. It sets the following variable, -@code{major-mode}, to the subsequent value, which is @code{text-mode}. -The single-quote before @code{text-mode} tells Emacs to deal directly -with the @code{text-mode} symbol, not with whatever it might stand for. -@xref{set & setq, , Setting the Value of a Variable}, -for a reminder of how @code{setq} works. -The main point is that there is no difference between the procedure you -use to set a value in your @file{.emacs} file and the procedure you use -anywhere else in Emacs. +We are already familiar with @code{setq}. It sets the following +variable, @code{major-mode}, to the subsequent value, which is +@code{text-mode}. The single-quote before @code{text-mode} tells +Emacs to deal directly with the @code{text-mode} symbol, not with +whatever it might stand for. @xref{setq, , Setting the Value of +a Variable}, for a reminder of how @code{setq} works. The main point +is that there is no difference between the procedure you use to set +a value in your @file{.emacs} file and the procedure you use anywhere +else in Emacs. @need 800 Here is the next line: commit cb3684e9dfa6603298540e3befe99962ff87d7ee Author: Eli Zaretskii Date: Wed Dec 20 15:55:41 2023 +0200 Fix script for some characters * lisp/international/characters.el (char-script-table): Fix script for 2 characters. * admin/unidata/blocks.awk: Fix script for Yijing Hexagram Symbols. (Bug#67924) diff --git a/admin/unidata/blocks.awk b/admin/unidata/blocks.awk index 80ce7478a45..dd6d5796044 100755 --- a/admin/unidata/blocks.awk +++ b/admin/unidata/blocks.awk @@ -60,6 +60,7 @@ BEGIN { alias["cjk strokes"] = "cjk-misc" alias["cjk symbols and punctuation"] = "cjk-misc" alias["halfwidth and fullwidth forms"] = "cjk-misc" + alias["yijing hexagram symbols"] = "cjk-misc" alias["common indic number forms"] = "north-indic-number" tohex["a"] = 10 @@ -94,7 +95,7 @@ function name2alias(name , w, w2) { if (alias[name]) return alias[name] else if (name ~ /for symbols/) return "symbol" else if (name ~ /latin|combining .* marks|spacing modifier|tone letters|alphabetic presentation/) return "latin" - else if (name ~ /cjk|yijing|enclosed ideograph|kangxi/) return "han" + else if (name ~ /cjk|enclosed ideograph|kangxi/) return "han" else if (name ~ /arabic/) return "arabic" else if (name ~ /^greek/) return "greek" else if (name ~ /^coptic/) return "coptic" diff --git a/lisp/international/characters.el b/lisp/international/characters.el index 21e2b59a1a4..1f002ab723a 100644 --- a/lisp/international/characters.el +++ b/lisp/international/characters.el @@ -1480,6 +1480,9 @@ use-default-char-width-table ;; Fix some exceptions that blocks.awk/Blocks.txt couldn't get right. (set-char-table-range char-script-table '(#x2ea . #x2eb) 'bopomofo) (set-char-table-range char-script-table #xab65 'greek) +(set-char-table-range char-script-table #x16fe0 'tangut) +(set-char-table-range char-script-table #x16fe1 'nushu) + ;;; Setting unicode-category-table. commit 2922d683b7899b8b580cbff466478617ea7ad5ad Author: Eli Zaretskii Date: Tue Dec 19 18:53:18 2023 +0200 ; * src/treesit.c (treesit_traverse_child_helper): Fix comment. diff --git a/src/treesit.c b/src/treesit.c index 04ea8958b96..93ed97212d7 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -3063,7 +3063,7 @@ treesit_traverse_child_helper (TSTreeCursor *cursor, if (!named || (named && ts_node_is_named (ts_tree_cursor_current_node(cursor)))) return true; - /* Else named is required and last child is not named node */ + /* Else named is required and last child is not named node. */ if (treesit_traverse_sibling_helper(cursor, false, true)) return true; else commit 7b315e8a5c966f8d11a4f646db4e29b989b56ab1 Author: Denis Zubarev Date: Sun Nov 12 01:42:42 2023 +0300 Fix an issue when searching subtree backward (bug#67117) * src/treesit.c (treesit_traverse_child_helper): Do not call treesit_traverse_sibling_helper when the named node is required and the last child is the named node. Otherwise treesit_traverse_sibling_helper will move cursor to the previous sibling and last node will be skipped. * test/src/treesit-tests.el (treesit-search-subtree-forward-1): (treesit-search-subtree-backward-1): Add tests. diff --git a/src/treesit.c b/src/treesit.c index 45de82ec096..04ea8958b96 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -3061,9 +3061,9 @@ treesit_traverse_child_helper (TSTreeCursor *cursor, /* First go to the last child. */ while (ts_tree_cursor_goto_next_sibling (cursor)); - if (!named) + if (!named || (named && ts_node_is_named (ts_tree_cursor_current_node(cursor)))) return true; - /* Else named... */ + /* Else named is required and last child is not named node */ if (treesit_traverse_sibling_helper(cursor, false, true)) return true; else diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el index 69db37fc0b4..9ba3a9340c1 100644 --- a/test/src/treesit-tests.el +++ b/test/src/treesit-tests.el @@ -1083,6 +1083,36 @@ treesit-defun-navigation-top-level treesit--ert-defun-navigation-python-program treesit--ert-defun-navigation-top-level-master))) +(ert-deftest treesit-search-subtree-forward-1 () + "Test search subtree forward." + (skip-unless (treesit-language-available-p 'python)) + (require 'python) + (python-ts-mode) + (insert "Temp(1, 2)") + (goto-char (point-min)) + (let ((node (treesit-search-subtree + (treesit--thing-at (point) "call") + (lambda (n) (equal (treesit-node-type n ) "integer"))))) + + (should node) + (should (equal (treesit-node-text node) "1")))) + +(ert-deftest treesit-search-subtree-backward-1 () + "Test search subtree with backward=t." + (skip-unless (treesit-language-available-p 'python)) + (require 'python) + (python-ts-mode) + (insert "Temp(1, 2)") + (goto-char (point-min)) + (let ((node (treesit-search-subtree + (treesit--thing-at (point) "call") + (lambda (n) (equal (treesit-node-type n ) "integer")) + t))) + + (should node) + (should (equal (treesit-node-text node) "2")))) + + ;; TODO ;; - Functions in treesit.el ;; - treesit-load-name-override-list commit 03625c2fefa682f74775abc1e223e17557d58bc7 Author: Christophe Deleuze Date: Mon Dec 18 11:13:30 2023 +0100 Fix passive mode for tnftp client in ange-ftp.el. * lisp/net/ange-ftp.el (ange-ftp-passive-mode): Fix passive mode result string for tnftp client. (Bug#67865) Copyright-paperwork-exempt: yes diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el index 4bf87c14f31..b8e8c3f0c33 100644 --- a/lisp/net/ange-ftp.el +++ b/lisp/net/ange-ftp.el @@ -2164,7 +2164,7 @@ ange-ftp-get-process proc))) (defun ange-ftp-passive-mode (proc on-or-off) - (if (string-match (concat "Passive mode " on-or-off) + (if (string-match (concat "Passive mode:? " on-or-off) (cdr (ange-ftp-raw-send-cmd proc (concat "passive " on-or-off) "Trying passive mode..." nil))) commit b6429b1c1c781655efc761e237a7ae0aa6a0d344 Author: Eli Zaretskii Date: Sun Dec 17 09:07:11 2023 +0200 ; Improve documentation of ispell.el's dictionary database * lisp/textmodes/ispell.el (ispell-dictionary-base-alist) (ispell-dictionary-alist): Doc fixes. (Bug#67857) diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index 48d48b07937..6b048a8a805 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -522,7 +522,12 @@ ispell-dictionary-base-alist "[^A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]" "[']" nil ("-C") "~list" iso-8859-1) ("hebrew" "[\340\341\342\343\344\345\346\347\350\351\353\352\354\356\355\360\357\361\362\364\363\367\366\365\370\371\372]" "[^\340\341\342\343\344\345\346\347\350\351\353\352\354\356\355\360\357\361\362\364\363\367\366\365\370\371\372]" "" nil ("-B") nil cp1255)) - "Base value for `ispell-dictionary-alist'.") + "Base value for `ispell-dictionary-alist'. + +Note that when the speller program is \"aspell\" or \"hunspell\", +some parts of the database, notably OTHERCHARS, will be overridden +by parsing the dictionary data files, see `ispell-aspell-find-dictionary' +and `ispell-parse-hunspell-affix-file'.") (defvar ispell-dictionary-alist nil "An alist of dictionaries and their associated parameters. @@ -577,7 +582,11 @@ ispell-dictionary-alist Note that with \"ispell\" as the speller, the CASECHARS and OTHERCHARS slots of the alist should contain the same character set as casechars and otherchars in the LANGUAGE.aff file \(e.g., -english.aff). Aspell and Hunspell don't have this limitation.") +english.aff). Aspell and Hunspell don't have this limitation. +Allso, when the speller program is \"aspell\" or \"hunspell\", +some parts of the database, notably OTHERCHARS, will be determined +by parsing the dictionary data files, see `ispell-aspell-find-dictionary' +and `ispell-parse-hunspell-affix-file'.") (defvar ispell-really-aspell nil "Non-nil if we can use Aspell extensions.") commit 75cc15934123b1ffc7d801aa245259585cb8357f Author: Eli Zaretskii Date: Sun Dec 17 08:09:22 2023 +0200 ; * etc/PROBLEMS: Update the "GnuPG hangs" entry. diff --git a/etc/PROBLEMS b/etc/PROBLEMS index f290b86cb8a..8f0e7864305 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -532,7 +532,9 @@ The solution is to use gawk (GNU awk). This is known to happen with GnuPG v2.4.1. The only known workaround is to downgrade to a version of GnuPG older than 2.4.1 (or, in the future, upgrade to a newer version which solves the problem, when such -a fixed version becomes available). +a fixed version becomes available). Note that GnuPG v2.2.42 and later +also has this problem, so you should also avoid those later 2.2.4x +versions; v2.2.41 is reported to work fine. *** EasyPG loopback pinentry does not work with gpgsm. commit 67d9af1c074e0b0ad301ecca91f7bae0531076d1 Author: Stefan Kangas Date: Sat Dec 16 20:33:04 2023 +0100 Fix using disabled command without a docstring * lisp/novice.el (disabled-command-function): Fix error when the disable command has no docstring. (Bug#67835) diff --git a/lisp/novice.el b/lisp/novice.el index 05e4bfc91c9..907126ab49b 100644 --- a/lisp/novice.el +++ b/lisp/novice.el @@ -67,9 +67,10 @@ disabled-command-function "Here's the first part of its description:\n\n") ;; Keep only the first paragraph of the documentation. (with-temp-buffer - (insert (condition-case () - (documentation cmd) - (error "<< not documented >>"))) + (insert (or (condition-case () + (documentation cmd) + (error nil)) + "<< not documented >>")) (goto-char (point-min)) (when (search-forward "\n\n" nil t) (delete-region (match-beginning 0) (point-max))) commit f68f3500236bb18b92e4b1a2c0c1b4ede528046e Author: Eli Zaretskii Date: Sat Dec 16 21:21:33 2023 +0200 Improve documentation of text properties handling when yanking * doc/lispref/text.texi (Text Properties): Mention special handling of text properties while yanking. diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 8fa2100ba11..9759d46ee69 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -2945,7 +2945,10 @@ Text Properties Copying text between strings and buffers preserves the properties along with the characters; this includes such diverse functions as -@code{substring}, @code{insert}, and @code{buffer-substring}. +@code{substring}, @code{insert}, and @code{buffer-substring}. Killing +and then yanking text (@pxref{The Kill Ring}) also preserves the +properties, except that some properties are handled specially and +might be removed when text is yanked; @pxref{Yanking}. @menu * Examining Properties:: Looking at the properties of one character. commit 06c399914fa868474938c2d00dae96f228e70fbf Author: skykanin <3789764+skykanin@users.noreply.github.com> Date: Sat Dec 16 16:08:57 2023 +0100 Eglot: Add Uiua language server * lisp/progmodes/eglot.el (eglot-server-programs): Add Uiua language server. (Bug#67850) Copyright-paperwork-exempt: yes diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 967d86955a4..02469615544 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -259,7 +259,8 @@ eglot-server-programs '(("marksman" "server") ("vscode-markdown-language-server" "--stdio")))) (graphviz-dot-mode . ("dot-language-server" "--stdio")) - (terraform-mode . ("terraform-ls" "serve"))) + (terraform-mode . ("terraform-ls" "serve")) + ((uiua-ts-mode uiua-mode) . ("uiua" "lsp"))) "How the command `eglot' guesses the server to start. An association list of (MAJOR-MODE . CONTACT) pairs. MAJOR-MODE identifies the buffers that are to be managed by a specific