1

I am typing a Tex file with Emacs and I want to be able to include the relative path of an image file name from inside Emacs.

For example, my Tex file that is being opened in Emacs is located at ~/mydir/mytex.tex. The image file whose path I want to import is located in ~/mydir/figdir/fig1.png. How can I get the path ./figdir/fig1.png from inside Emacs also with autocomplete feature, e.g. if I type the letter f it should suggest figdir among other possible files or directories starting with f.

I feel that this kind of thing is not necessarily something that is only relevant with LaTeX. It should apply generally with any kind of docs opened by Emacs.

  • How is Emacs to know, when you hit f, that you want to insert a file name? Autocompletion completes text already in the buffer. If you have the beginning of a file name in the buffer then it could be completed, for instance. But Emacs needs to be able to recognize that it's the beginning of a file name (and so propose file names as completions), or you need to somehow tell Emacs that you want to insert a file name (and so it proposes file-name candidates). – Drew Nov 10 '18 at 18:30
0

This might get you at least part way there, though it's not too clear to me what you're asking.

Invoke the command shown here from a key (e.g. C-o), to insert a file name into the current buffer. You can navigate through the file hierarchy to choose a file name, which is then inserted into the current buffer.

(This is a dumbed-down version of what is bound to C-M-F in the minibuffer, in Icicles - see Completion On Demand. Anytime the minibuffer is active it lets you use completion to insert a file name in the minibuffer, for further editing there.)

(defun my-read+insert-file-name (dir-too-p)
  "Read a file name and insert it, without its directory, by default.
With a prefix argument, insert its directory also.
Return the string that was inserted."
  (interactive "P")
  (let ((completion-ignore-case        (memq system-type '(ms-dos windows-nt cygwin)))
        (enable-recursive-minibuffers  t)
        (use-dialog-box                nil)
        (minibuffer-local-completion-map
         (let ((map  (make-sparse-keymap)))
           (set-keymap-parent map minibuffer-local-completion-map)
           map))
        (minibuffer-local-must-match-map
         (let ((map  (make-sparse-keymap)))
           (set-keymap-parent map minibuffer-local-must-match-map)
           map))
        result)
    (setq result  (read-file-name "Choose file: "))
    (unless dir-too-p                   ; Remove parent dir.
      (setq result  (if (file-directory-p result)
                        (file-name-as-directory
                         (file-name-nondirectory (directory-file-name result)))
                      (file-name-nondirectory result))))
    (insert result)
    result))

(global-set-key "\C-o" 'my-read+insert-file-name)
  • How to use it? I tried to go to minibuffer with "C-x-f" (open file) and pressing ctrl+M+S+f, the moment I press M it prompts a list of file name in the current directory. – nougako Nov 12 '18 at 11:48
  • I guess you're asking about the use of C-M-F in Icicles, not about the code shown here. I added a link here to its description. It lets you insert a file name into the minibuffer using completion (and navigating like read-file-name), even when the minibuffer is not reading with completion. – Drew Nov 12 '18 at 16:18
  • But in this answer you would just invoke the command shown here from a key, to insert a file name into the current buffer (typically not the minibuffer). I'm guessing that's what you're requesting. Just try C-o (example key binding), to see. You can navigate through the file hierarchy to choose a file name, which is then inserted into the current buffer. – Drew Nov 12 '18 at 16:20
  • I see, it can only insert the filename, not the relative or full path. But it is still pretty helpful. – nougako Nov 13 '18 at 9:22
  • Not sure what you mean. As defined, you can insert just the nondirectory part of the file name (aka relative) or, with a prefix arg, the full file name (aka absolute). Isn't that what you requested? If not, you can change that part of the code - result is the full file name. You can grab any part of it you want, using appropriate file-name functions. – Drew Nov 13 '18 at 14:14

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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