1

The traditional way of opening a file is via C-x C-f (find-file). I don't know since when this has been the case, but in Emacs 27.0.50 (Linux), using the menu bar's File -> Open File invokes the GTK file selection dialog.

GTK File Selection Dialog

Since I prefer this behaviour, I'd like to know:

  1. How can I invoke this GTK file selector via M-x?
  2. What can I write in my Emacs init file so that C-x C-f opens this GTK dialog when I'm running Emacs on X Windows, but reverts to the traditional behaviour when running in the terminal mode?
1

You ask about initiation of the selection by M-x. I don't know whether there is a simple way to cause use of the dialog box even when you do not use a menu or tool-bar button (typically initiated with a mouse). (But it's also not clear to me what M-x has to do with selecting a file, unless you mean M-x find-file or some such.)

Anyway, the reason the file selection box is shown is likely because of the settings of options use-file-dialog and use-dialog-box, which you can customize.

In addition, since you have GTK, you can customize options x-gtk-show-hidden-files and x-gtk-file-dialog-help-text, which affect the behavior of the file selection box.

See the Emacs manual, node Dialog Boxes.

C-h v use-file-dialog tells us:

use-file-dialog is a variable defined in C source code. Its value is t

Documentation:

Non-nil means mouse commands use a file dialog to ask for files.

This applies to commands from menus and tool bar buttons even when they are initiated from the keyboard. If use-dialog-box is nil, that disables the use of a file dialog, regardless of the value of this variable.

This variable was introduced, or its default value was changed, in version 22.1 of Emacs.

To your second question: You can test whether Emacs is running in a window system (GUI) or in terminal mode, using predicate display-graphic-p. C-h f tells us:

display-graphic-p is a compiled Lisp function in frame.el.

(display-graphic-p &optional DISPLAY)

Return non-nil if DISPLAY is a graphic display.

Graphical displays are those which are capable of displaying several frames and several different fonts at once. This is true for displays that use a window system such as X, and false for text-only terminals. DISPLAY can be a display name, a frame, or nil (meaning the selected frame’s display).

1

find-file uses the minibuffer or the GTK+ dialog depending on what next-read-file-uses-dialog-p returns. So you can force the dialog by overriding this function:

(defun vf-find-file-with-dialog ()
  (interactive)
  ;; `flet' is deprecated, but I don't know enough Emacs Lisp
  ;; to make the non-deprecated `cl-flet' work here.
  (flet ((next-read-file-uses-dialog-p () t))
    (call-interactively 'find-file)))

Alternatively, here’s a hacky but perhaps more general workaround using Zenity:

(defun vf-find-file-with-zenity ()
  (interactive)
  (let ((name (string-trim-right (shell-command-to-string
                                  "zenity --file-selection 2>/dev/null"))))
    (unless (string-empty-p name) (find-file name))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.