2

Sometimes it may happen that we would like to open the current buffer in another text editor (notepad, gedit, texmaker, ....). What are the best ways to do it?

4
  • Are you talking about sending the current buffer text as well? Jan 10, 2015 at 3:32
  • 2
    "But why would you want to?" :(
    – lily
    Jan 10, 2015 at 6:25
  • @IstvanChung It may happen! For example you are editing an HTML file and you would like to open it in a web browser, also for the case where your language is not supported by the spell-checking engines of Emacs. And many other examples.
    – Name
    Jan 10, 2015 at 9:37
  • @SeanAllred yes.
    – Name
    Jan 10, 2015 at 9:40

3 Answers 3

6

You could use something such as the following

(defun open-external (&optional editor)
  (interactive "sEditor to use: ")
  (let ((file (buffer-file-name (current-buffer))))
    (if (executable-find editor)
        (if file
            (shell-command (format "%s %s"
                                   (executable-find editor)
                                   file))
          (user-error "Current buffer has no associated file."))
      (user-error "Editor (%s) not found on path" editor))))

This uses buffer-file-name rather than buffer-name to ensure you get the associated file from the filesystem. It also validates that both the file and the editor selected are found on path (or explicitly pointed to).

4
  • Nice! Hadn't known about executable-find.
    – Dan
    Jan 9, 2015 at 21:22
  • I think you can simplify this by dropping the let call. You can access the buffer-file-name directly as a variable, you don't need to call it and store the value.
    – robru
    Jan 11, 2015 at 18:53
  • The let is more personal preference. Have to access file twice so rather use a temporary variable than type it out fully both times. Jan 21, 2015 at 14:37
  • A few remarks (only the first has some importance) (i) I suggest using call-process instead of shell-command, otherwise you'd have to quote the filename for the shell. (ii) as was pointed out, buffer-file-name is also a variable name, which you can use directly (as for the function, (current-buffer) is used by default) (iii) you could define a temporary variable for (executable-find editor) too (I don't know how costly that function call is, but I guess this is more than a call to the function buffer-file-name !)
    – YoungFrog
    May 13, 2015 at 8:49
3

This version opens the buffer in an external program (use a prefix to change the default). If the buffer is not visiting a file, open it up in a temporary file:

(defvar alternate-editor "gedit"
  "Editor to use when visiting a buffer outside of emacs.")

(defun open-in-alternate-editor (&optional arg)
  "Open buffer in alternative editor.  If buffer is unsaved,
bring it up in a temporary file.  With prefix argument, ask for
the editor to use."
  (interactive "P")
  (let ((edit (executable-find (if arg
                                   (read-from-minibuffer
                                    "Enter editor to use: "
                                    alternate-editor)
                                 alternate-editor)))
        (file (or (buffer-file-name)
                  (make-temp-file "unsaved-emacs-buffer-")))
        (buff (unless (buffer-file-name)
                (save-restriction (widen) (buffer-string)))))
    (when (null edit)
      (error "Can't find alternate editor"))
    (unless (buffer-file-name)
      (with-temp-file file
        (insert buff)))
    (start-process "Alternate Editor" nil edit file)))

Note that the defvar might be overkill -- you could just replace it with whatever string you like within the defun.

2

M-! (shell-command)

You could for example define your own command for edit that takes the current buffer name as input

(defun ppop-open-in-gedit ()
  (interactive "")
  (shell-command (format  "gedit %s" (buffer-file-name))))

(global-set-key (kbd "<f10>") 'ppop-open-in-gedit)

I would check if the buffer has a corresponding file, but you get the idea.

1
  • 2
    (buffer-file-name) is better than (buffer-name (current-buffer)) here. They both default to the current buffer, so you don't need to specify it explicitly.
    – Tyler
    Jan 9, 2015 at 20:55

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.