|
|
;;; osx-clipboard.el --- Use the OS X clipboard from terminal Emacs
|
|
|
|
|
|
;; Copyright (C) 2014 Jon Oddie <jonxfield@gmail.com>
|
|
|
|
|
|
;; Author: Jon Oddie <jonxfield at gmail.com>
|
|
|
;; Created: 11 October 2014
|
|
|
;; Version: 0.1
|
|
|
;; Package-Version: 20141012.17
|
|
|
;; Url: https://github.com/joddie/osx-clipboard-mode
|
|
|
|
|
|
;; This file is NOT part of GNU Emacs.
|
|
|
|
|
|
;; This program is free software: you can redistribute it and/or
|
|
|
;; modify it under the terms of the GNU General Public License as
|
|
|
;; published by the Free Software Foundation, either version 3 of the
|
|
|
;; License, or (at your option) any later version.
|
|
|
;;
|
|
|
;; This program is distributed in the hope that it will be useful, but
|
|
|
;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
;; General Public License for more details.
|
|
|
;;
|
|
|
;; You should have received a copy of the GNU General Public License
|
|
|
;; along with this program. If not, see `http://www.gnu.org/licenses/'.
|
|
|
|
|
|
;;;; Commentary:
|
|
|
|
|
|
;; Sometimes it is useful to run Emacs in a plain terminal window, even
|
|
|
;; when a graphical display is available, but it's a nuisance if you need
|
|
|
;; to copy and paste from the text-mode Emacs to another program. This is
|
|
|
;; a tiny minor mode which lets Emacs on Mac OS X use the system clipboard
|
|
|
;; even when running in a text terminal, via the external `pbpaste' and
|
|
|
;; `pbcopy' programs.
|
|
|
|
|
|
;; To enable it, either customize the variable `osx-clipboard-mode' to `t',
|
|
|
;; or add the following line to your init file:
|
|
|
|
|
|
;; ,----
|
|
|
;; | (osx-clipboard-mode +1)
|
|
|
;; `----
|
|
|
|
|
|
;; Attempting to enable this mode an a non-OS-X system or in a graphical
|
|
|
;; Emacs will do nothing, so it should be safe to enable it unconditionally
|
|
|
;; even if you share your configuration between multiple machines.
|
|
|
|
|
|
;;;; Code:
|
|
|
|
|
|
;;;###autoload
|
|
|
(defgroup osx-clipboard nil
|
|
|
"Enable the OS X clipboard when running in a text terminal."
|
|
|
:group 'environment
|
|
|
:tag "OS X Clipboard"
|
|
|
:link '(url-link "http://github.com/joddie/osx-clipboard-mode"))
|
|
|
|
|
|
;;;###autoload
|
|
|
(define-minor-mode osx-clipboard-mode
|
|
|
"Kill and yank using the OS X clipboard when running in a text terminal.
|
|
|
|
|
|
This mode allows Emacs to use the OS X system clipboard when
|
|
|
running in the terminal, making killing and yanking behave
|
|
|
similarly to a graphical Emacs. It is not needed in a graphical
|
|
|
Emacs, where NS clipboard integration is built in.
|
|
|
|
|
|
It sets the variables `interprogram-cut-function' and
|
|
|
`interprogram-paste-function' to thin wrappers around the
|
|
|
\"pbcopy\" and \"pbpaste\" command-line programs.
|
|
|
|
|
|
Consider also customizing the variable
|
|
|
`save-interprogram-paste-before-kill' to `t' for best results."
|
|
|
:global t
|
|
|
:lighter " OSX-Clipboard" :tag "OS X Clipboard Mode"
|
|
|
:group 'osx-clipboard
|
|
|
(if (not (and (eq system-type 'darwin) (not window-system)))
|
|
|
(progn
|
|
|
(when (called-interactively-p 'any)
|
|
|
(message "`osx-clipboard-mode' only works in text terminals under OS X"))
|
|
|
(setq osx-clipboard-mode nil))
|
|
|
(if osx-clipboard-mode
|
|
|
;; Turn on
|
|
|
(setq interprogram-cut-function #'osx-clipboard-cut-function
|
|
|
interprogram-paste-function #'osx-clipboard-paste-function)
|
|
|
;; Turn off
|
|
|
(setq interprogram-cut-function nil
|
|
|
interprogram-paste-function nil))))
|
|
|
|
|
|
(defun osx-clipboard-cut-function (text &rest ignore)
|
|
|
"Copy TEXT to the OS X clipboard using \"pbpaste\".
|
|
|
|
|
|
This is set as the value of `interprogram-cut-function' by
|
|
|
`osx-clipboard-mode'. It should only be used when Emacs is running in a
|
|
|
text terminal."
|
|
|
(with-temp-buffer
|
|
|
(insert text)
|
|
|
(with-demoted-errors "Error calling pbcopy: %S"
|
|
|
(call-process-region (point-min) (point-max) "pbcopy"))))
|
|
|
|
|
|
(defvar osx-clipboard-last-selected-text nil)
|
|
|
|
|
|
(defun osx-clipboard-paste-function ()
|
|
|
"Return the value of the OS X clipboard using \"pbcopy\".
|
|
|
|
|
|
This is set as the value of `interprogram-paste-function' by
|
|
|
`osx-clipboard-mode'. It should only be used when Emacs is running in a
|
|
|
text terminal."
|
|
|
(with-temp-buffer
|
|
|
(with-demoted-errors "Error calling pbpaste: %S"
|
|
|
(call-process "pbpaste" nil t)
|
|
|
(let ((text (buffer-substring-no-properties (point-min) (point-max))))
|
|
|
;; The following logic is adapted from `x-selection-value'
|
|
|
;; in `ns-win.el.gz'
|
|
|
(cond
|
|
|
((or
|
|
|
;; Avoid copying an empty clipboard, or copying the same
|
|
|
;; text twice
|
|
|
(not text)
|
|
|
(eq text osx-clipboard-last-selected-text)
|
|
|
(string= text "")
|
|
|
(string= text (car kill-ring))) nil)
|
|
|
((string= text osx-clipboard-last-selected-text)
|
|
|
;; Record the newer string, so subsequent calls can use the `eq' test.
|
|
|
(setq osx-clipboard-last-selected-text text)
|
|
|
nil)
|
|
|
(t
|
|
|
(setq osx-clipboard-last-selected-text text)))))))
|
|
|
|
|
|
(provide 'osx-clipboard)
|
|
|
|
|
|
;;; osx-clipboard.el ends here
|