Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ emacs-everywhere-linux-copy-function emacs-everywhere-paste-cmd #40

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion README.org
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,26 @@ C-k= still copies the content to the clipboard, but never pastes.
-----

^{*†*} This requires the Emacs daemon to be running, but that's super easy.
Just call =emacs --daemon= and you're sorted!
Just call =emacs --daemon= or =M-x server-start= and you're sorted!

* Customize

** Example hook
The default simulated key chord pastes into Pidgin as a single line. To preserve newlines, the desired combo is =Control+V= (instead of the default =Shift+Insert=). Here we create a function that temporarily modifies the paste command when emacs-everywhere was launched with Pidgin focused.
#+begin_src elisp
;; "Paste as plaintext" using "Control Shift V" for GTK app Pidgin IM
(defun emacs-everywhere-pidgin-paste ()
(when (string= (emacs-everywhere-app-class emacs-everywhere-current-app) "Pidgin")
(set 'emacs-everywhere-paste-cmd
'("xdotool" "key" "--clearmodifiers" "Control+V"))))

(add-hook 'emacs-everywhere-init-hooks 'emacs-everywhere-pidgin-paste)
#+end_src

** Highlights

Window and app names that will open in markdown mode are enumerated in =emacs-everywhere-markdown-windows= and =emacs-everywhere-markdown-apps=.

How the clipboard is handled can be redefined using =emacs-everywhere-linux-copy-function= and =emacs-everywhere-paste-cmd=.

See =M-x customize-groups [RET] emacs-everywhere= for the full list. Or peak at the source.
61 changes: 49 additions & 12 deletions emacs-everywhere.el
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,15 @@
:type 'boolean
:group 'emacs-everywhere)

(defcustom emacs-everywhere-paste-cmd nil
"How to paste back. List like (cmd arg1 arg2). Used with `emacs-everywhere-paste'.
Example: '(\"xdotool\" \"key\" \"--clearmodifiers\" \"Shift+Insert\")
Consider pairing with `make-local-variable' in `emacs-everywhere-init-hooks'"
:type 'sexp
:group 'emacs-everywhere)

(defcustom emacs-everywhere-markdown-windows
'("Stack Exchange" "Stack Overflow" "Reddit" ; Sites
'("Stack Exchange" "Stack Overflow" "Reddit" ; Sites
"Pull Request" "Issue" "Comparing .*\\.\\.\\." ; Github
"Discord")
"For use with `emacs-everywhere-markdown-p'.
Expand Down Expand Up @@ -224,6 +231,45 @@ buffers.")
(org-ctrl-c-ctrl-c)
(emacs-everywhere-finish)))

(defun emacs-everywhere-what-paste-cmd ()
"What command to use to paste."
(cond (emacs-everywhere-paste-cmd
emacs-everywhere-paste-cmd)
((eq system-type 'darwin)
'("osascript"
"-e"
"tell application \"System Events\" to keystroke \"v\" using command down"))
(t
'("xdotool"
"key"
"--clearmodifiers"
"Shift+Insert"))))

(defun emacs-everywhere-paste ()
"Paste with operating system specific program or custom cmd"
(interactive)
(let* ((cmd-list (emacs-everywhere-what-paste-cmd))
(cmd (car cmd-list))
(args (cdr cmd-list)))
(eval `(call-process ,cmd nil nil nil ,@args))))

(defun emacs-everywhere-linux-copy ()
"Put the current buffer onto the clipboard."
(let ((inhibit-message t)
(require-final-newline nil)
write-file-functions)
(write-file buffer-file-name)
(pp (buffer-string))
(call-process "xclip" nil nil nil "-selection" "clipboard" buffer-file-name)))

(defcustom emacs-everywhere-linux-copy-function
#'emacs-everywhere-linux-copy
"A function to populate the clipboard. To be pasted into original app by `emacs-everywhere-paste'"
:type 'function
:group 'emacs-everywhere)



(defun emacs-everywhere-finish (&optional abort)
"Copy buffer content, close emacs-everywhere window, and maybe paste.
Must only be called within a emacs-everywhere buffer.
Expand All @@ -236,12 +282,7 @@ Never paste content when ABORT is non-nil."
(run-hooks 'emacs-everywhere-final-hooks)
(gui-select-text (buffer-string))
(unless (eq system-type 'darwin) ; handle clipboard finicklyness
(let ((inhibit-message t)
(require-final-newline nil)
write-file-functions)
(write-file buffer-file-name)
(pp (buffer-string))
(call-process "xclip" nil nil nil "-selection" "clipboard" buffer-file-name))))
(funcall emacs-everywhere-linux-copy-function)))
(sleep-for 0.01) ; prevents weird multi-second pause, lets clipboard info propagate
(let ((window-id (emacs-everywhere-app-id emacs-everywhere-current-app)))
(if (eq system-type 'darwin)
Expand All @@ -255,11 +296,7 @@ Never paste content when ABORT is non-nil."
(when (and (frame-parameter nil 'emacs-everywhere-app)
emacs-everywhere-paste-p
(not abort))
(if (eq system-type 'darwin)
(call-process "osascript" nil nil nil
"-e" "tell application \"System Events\" to keystroke \"v\" using command down")
(call-process "xdotool" nil nil nil
"key" "--clearmodifiers" "Shift+Insert"))))
(emacs-everywhere-paste)))
;; Clean up after ourselves in case the buffer survives `server-buffer-done'
;; (b/c `server-existing-buffer' is non-nil).
(emacs-everywhere-mode -1)
Expand Down