In Emacs, how to have "File/Open Recent" menu to ignore currently opened ones?

81 views Asked by At

In Emacs, the "File" menu has a "Open Recent" entry, which displays the N first elements of recentf-list variable.

I understand the recentf-list variable must contain all latest opened files (ordered by most recently opened), but "File/Open Recent" unfortunately shows the same files, including files which are currently opened in Emacs: Selecting one [already opened] will simply switch to the corresponding buffer (not related to an "Open Recent" action).

Would it be possible to exclude (in "File/Open Recent" only) all files currently opened in Emacs ?

Example:

Below is my current buffers list. I did comment the "irrelevant" ones. I have currently 9 opened files.

(buffer-list)
(   ;; #<buffer *scratch*>
    ;; #<buffer *Async-native-compile-log*>
    ;; #<buffer *Minibuf-1*>
    ;; #<buffer *temp-0*>
    
 [...]
 
 #<buffer passwd>
 #<buffer c/Makefile>
 #<buffer brchess/Makefile>
    ;; #<buffer *Messages*>
    ;; #<buffer *scratch*>
    ;; #<buffer  *Minibuf-0*>
    ;; #<buffer *Native-compile-Log*>
    
 [...]
 
 #<buffer boot-disk.org>
 #<buffer beaglebone-buster-setup.org>
 #<buffer init.el>
 #<buffer emacs-cheatsheet.org>
 #<buffer 2023/Makefile>
 #<buffer list-pgn-games.php>
    ;; #<buffer *Compile-Log*>
    
 [...])

Below is recentf-list value (first 9 are currently opened - see above). The "File/Open Recent" shows first 10 elements:

("/etc/passwd"**
 "/home/br/dev/www/devs/php/chess/list-pgn-games.php"**
 "/home/br/dev/advent-of-code/2023/Makefile"**
 "/home/br/org/emacs-cheatsheet.org"**
 "/home/br/.emacs.d/init.el"**
 "/home/br/org/beaglebone-buster-setup.org"**
 "/home/br/org/boot-disk.org"**
 "/home/br/dev/tools/c/Makefile"**
 "/home/br/dev/brchess/Makefile"**
 
 ;; files above are currently opened in Emacs
 
 "/home/br/list-all-ppa.sh"
 
 ;; "File/Open Recent" (10 entries) shows all above entries, first 9 are useless.

 "/home/br/dev/userspace-rcu/include/urcu/arch/x86.h"
 "/home/br/dev/userspace-rcu/include/urcu/arch/generic.h"
 "/home/br/dev/userspace-rcu/doc/examples/list/cds_list_add_rcu.c"
 "/home/br/dev/userspace-rcu/include/urcu/list.h"
 "/home/br/dev/brchess/include/debug.h"
 "/home/br/dev/tools/config/home/.bashrc.br.lorien"
 "/home/br/dev/tools/config/home/.bashrc.br"
 "/home/br/dev/test/Makefile"
 "/home/br/dev/test/definitions.h"
 "/home/br/dev/test/definitions.c"
 "/home/br/dev/test/main.c"
 "/home/br/.bashrc.br")

In this example, I would like "File/Open Recent" to skip the 9 first entries.

Note: I am not really fluent in Elisp, unfortunately.

EDIT 1, following first answer received: I believe altering recentf-list (with remove-if) will not work, as some information would be lost forever: When closing one of the 9 buffers above, it will not "re-appear" in menu (it should), and likely ~/.emacs.d/recentf file will also lose some information.

1

There are 1 answers

2
Drew On

You can customize option recentf-exclude or recentf-keep, or both, adding a predicate that filters however you like (e.g., exclude files currently visited in a buffer). Function buffer-alist gives you the list of currently existing buffers. You can filter that using a function such as cl-delete-if(-not) or cl-remove-if(-not).