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?

  • Are you talking about sending the current buffer text as well? – Sean Allred Jan 10 '15 at 3:32
  • 2
    "But why would you want to?" :( – Lily Chung Jan 10 '15 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 '15 at 9:37
  • @SeanAllred yes. – Name Jan 10 '15 at 9:40
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).

  • Nice! Hadn't known about executable-find. – Dan Jan 9 '15 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 '15 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. – Jonathan Leech-Pepin Jan 21 '15 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 '15 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.

  • 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 '15 at 20:55

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.