5

I started to use Dired. The movie files will be opened by another external application (VLC) with the help of the package openwith.

So I would like to supress the confirmation File foobar.avi is too large, really open? (y or n) for movie files.

When exploring this feature, I found the variable large-file-warning-thresold, the docstring is:

The variable is large-file-warning-threshold. Documentation:

large-file-warning-threshold is a variable defined in `files.el'.
Its value is 10000000

Documentation:
Maximum size of file above which a confirmation is requested.
When nil, never request confirmation.

You can customize this variable.

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

So I would like to disable this thresold for only specific extensions like .mp4 or .mkv, but don't change it for another extensions.

By reading the source, look at the function to open files: C-h k C-x C-f (or C-h f find-file RET). Click on files.el to browse the source file (you must have the Lisp sources installed). Don't read the code — it's pretty big — but search for parts of the message in that file. You'll find

(defun abort-if-file-too-large (size op-type filename)
  "If file SIZE larger than `large-file-warning-threshold', allow user to abort.
OP-TYPE specifies the file operation being performed (for message to user)."
  (when (and large-file-warning-threshold size
             (> size large-file-warning-threshold)
             (not (y-or-n-p
                   (format "File %s is large (%dMB), really %s? "
                           (file-name-nondirectory filename)
                           (/ size 1048576) op-type))))
    (error "Aborted")))

The message is only displayed when some conditions are met. The first condition is large-file-warning-threshold (interpreted as a boolean), i.e. large-file-warning-threshold must be non-nil. So you can disable the message by setting that variable to nil. (You can confirm that it's a global variable by looking at its definition in the same file — it's a customizable item, and the documentation explains how it's used if you aren't familiar enough with Lisp and only figured out that the variable mattered in some way.)

So I would add the condition for .mp4 and .mkv4 files.

Any idea how I could achieve that, without fiddling with the source code for Dired? I could use defadvice, but it's currently unclear to me how I could apply extra conditional for confirmation messages.

3 Answers 3

7

You're on the right track. This should do the trick:

(defvar my-ok-large-file-types
  (rx "." (or "mp4" "mkv") string-end)
  "Regexp matching filenames which are definitely ok to visit,
even when the file is larger than `large-file-warning-threshold'.")

(defadvice abort-if-file-too-large (around my-check-ok-large-file-types)
  "If FILENAME matches `my-ok-large-file-types', do not abort."
  (unless (string-match-p my-ok-large-file-types (ad-get-arg 2))
    ad-do-it))
(ad-activate 'abort-if-file-too-large)
8
  • it works like a charm, thanks for that! However, I had some difficulty to understand how you figured it out. Maybe you could explain in which ways your snippet works? Thanks in advance.
    – ReneFroger
    Oct 3, 2015 at 13:15
  • 1
    Sure. abort-if-file-too-large raises an error if its conditions are met, and does nothing at all otherwise. As such, all we need to do here is to wrap our own condition around the function, such that the original definition isn't executed at all if we're happy with the filename. In around advice, ad-do-it is a token which calls the original function; so here that only happens if the filename (which is argument 2 of the original function) isn't a match for our regexp.
    – phils
    Oct 3, 2015 at 14:06
  • Thanks for your clear explaination, I struggled about the ad-thingy. I'm impressed with your solution after all... how long do you work with Emacs/Elisp, by the way?
    – ReneFroger
    Oct 3, 2015 at 14:35
  • 1
    If you can find an Emacs version prior to Emacs 24.4, then you can consult the doc about defadvice, starting with node Defining Advice of the Elisp manual. Unfortunately, this doc was (unwisely, IMHO) removed with 24.4 and later. (Maybe you can find an older manual on line.)
    – Drew
    Oct 3, 2015 at 16:11
  • 1
    You can find some of the old doc in the Commentary of library advice.el. Thank goodness for that. As for who removed it from the Elisp manual, and why, see bug 16491. The new advice system has some features that the old does not, and vice versa. But the old was simply tossed, and its doc along with it.
    – Drew
    Oct 3, 2015 at 16:22
1

This is an elaboration of phils' answer that sets my-ok-large-file-types automatically using the value of openwith-associations:

(define-advice abort-if-file-too-large
    (:around (orig-fn size op-type filename &optional offer-raw) unless-openwith-handles-it)
  "Do not abort if FILENAME is handled by Openwith."
  (let ((my-ok-large-file-types (mapconcat 'car openwith-associations "\\|")))
    (unless (string-match-p my-ok-large-file-types filename)
      (funcall orig-fn size op-type filename offer-raw))))

The setting of my-ok-large-file-types works like this: my-ok-large-file-types is a list of lists with a structure like ((<regexp> <application> <file>) (<regexp> <application> <file>) …). You can make a big regexp that matches any file handled by Openwith by combining all the <regexp> elements using or operators. In code, that's (mapconcat 'car openwith-associations "\\|"): car returns the first element of a list, mapconcat applies car to all elements of openwith-associations and concatenates the results separating them with \\|, the or operator (see (elisp)Mapping Functions).

Another difference is that this advice is written using nadvice.el, which is the newer advice library. I don't know much about its technical advantages, for those I refer you to Practical benefits of new advice system in Emacs 24.4. Here, notice that all the arguments of abort-if-file-too-large are declared in the lambda list. That's what allows calling the original function's argument filename by name in (string-match-p my-ok-large-file-types filename), instead of having to use ad-get-arg as with the old advice.el library. Advices with the :around combinator additionally take the advised function's name as an argument. When you call the original function in your advice, you do it by invoking funcall or apply with that argument, in place of ad-do-it.

0

To suppress the question altogether, I followed your thought pattern above with this line:

(setq large-file-warning-threshold nil)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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