Open maxnikulin opened 3 years ago
I don't have a linux system to test changes on, so pull requests are welcome.
the problem is that you have to construct the xclip command with a file name in it the way it is written. If xclip can read from stdin we can probably avoid that. I don't have a way to verify it though, so I don't want to make that change.
I don't have a linux system to test changes on, so pull requests are welcome.
I am unaware concerning degree of severity of the issue on other operation systems. Generally temporary files should be created with some analogue of POSIX O_EXCL
flag causing error if a file having requested name already exists. Otherwise various races and rare but still hard to debug problems could appear. I agree that it could be tedious to carefully handle such cases.
I was curious concerning implementation details when you suggested the package in the mail list message. Earlier I was evaluating feasibility of a similar feature and realized emacs API does not allow to implement it without external tools. The cases when such feature is required are not frequent for me, but next time I will consider a pull request.
the problem is that you have to construct the xclip command with a file name in it the way it is written. If xclip can read from stdin we can probably avoid that. I don't have a way to verify it though, so I don't want to make that change.
xclip could get data from stdin but there is an issue with stdout (that should be explicitly closed) faced by tmux users astrand/xclip#20 "Not closing stdout when setting clipboard from stdin", workaround is described in Arch wiki as well https://wiki.archlinux.org/index.php/tmux#X_clipboard_integration
Ideally command could have a substitution, e.g. optionally quoted %f
that is expanded after splitting the string xclip -in -target text/html %f
into arguments array. Unfortunately I have not found ready to use function in elisp despite the task is not really rare and users could do something insecure instead.
this is only an issue on linux, for using xclip. The other platforms don't use this named tempfile. The command you are looking for is (format "xclip -in -target text/html %s" temp-file-name)
in the simplest form.
The command you are looking for is
(format "xclip -in -target text/html %s" temp-file-name)
No, I was writing about something like
(mapcar (lambda (arg)
(format-spec arg '((?f . "/tmp/a.html")
(?t . "text/html"))))
(split-string-and-unquote
"xclip -verbose -in -type %t -selection clipboard \"%f\""))
(format "%2$s, %3$s, %%, %1$s" "x" "y" "z")
syntax, and it is anyway less convenient than "f" for file and "t" for type convention.Concerning launching the command without temporary file, pseudoterminal created by start-process
is certainly redundant. I have not looked into emacs sources yet, so I have no guess why it decides to kill process immediately if -verbose
is not specified (related commit message in ox-clip is not detailed enough too). It seems, if pipe is used, emacs behaves better in respect to xclip
(setq pr (make-process :name "ox-clip" :command '("xclip" "-in" "-selection" "CLIPBOARD")
:connection-type 'pipe
:buffer nil
:filter (lambda (proc string) (message "%s" string))))
; (process-send-region)
(process-send-string pr "test")
(process-send-eof pr)
I still feel lack of basic operation in emacs interface to processes: close stdin file descriptor and the same for stdout.
Can you check out 977562f and let me know if it works ok for you? I think it solves this issue.
Also thanks for the tips above, I didn't know that format could do that! I also never remember the format-spec. It seems so old fashioned compared to things like s-format.
Please, do not hurry.
To make it working (to some extent) I have to modify the code
diff --git a/ox-clip.el b/ox-clip.el
index 6316f5d..37a4b1d 100644
--- a/ox-clip.el
+++ b/ox-clip.el
@@ -66,14 +66,14 @@
(file-name-directory (or load-file-name (locate-library "ox-clip")))))
"Absolute path to html-clip-w32.py."
:group 'ox-clip
- :type string)
+ :type 'string)
(defcustom ox-clip-osx-cmd
"textutil -inputencoding UTF-8 -stdin -format html -convert rtf -stdout | pbcopy"
"Command to copy formatted text on osX."
:group 'ox-clip
- :type string)
+ :type 'string)
(defcustom ox-clip-linux-cmd
@@ -399,8 +399,8 @@ R1 and R2 define the selected region."
ox-clip-osx-cmd)))
((eq system-type 'gnu/linux)
;; For some reason shell-command on region does not work with xclip.
- (let ((tmpfile (make-temp-file "ox-clip-" nil ".html"
- (with-current-buffer buf (buffer-string)))))
+ (let ((tmpfile (make-temp-file "ox-clip-" nil ".html")))
+ (with-current-buffer buf (append-to-file nil nil tmpfile))
(apply
'start-process "ox-clip" "*ox-clip*"
(split-string (format-spec ox-clip-linux-cmd
Problems:
emacs --no-init-file --execute '(setq temporary-file-directory (expand-file-name "~/My Temporary Documents"))' --load ox-clip.el ~/examples/org/test.org
make-process
to avoid additional question on quit if xclip process still handles selection. On linux clipboard content becomes unavailable after finishing of process (without any dialogues).The quotes were my mistake, thanks for reporting those.
I quoted the filename, which should make it work with spaces I think.
What happens with the tmpfile code? according to (make-temp-file PREFIX &optional DIR-FLAG SUFFIX TEXT)
the original version should work.
for removal of the tmp file, maybe the command could be "xclip -verbose -i \"%f\" -t text/html -selection clipboard && rm \"%f\""?
I think I have set the noquery flag. Can you check?
My variant: https://github.com/maxnikulin/ox-clip/commit/f04aa7e5f977e0c7b0007d17f959e225fa690c97 However I have not tested images (it requires some packages that are not currently installed).
I do not think, it is what you were going to achieve:
(split-string
(format-spec "xclip -verbose -i \"%f\" -t text/html -selection clipboard"
'((?f . "/home/ubuntu/My Temporary Documents/ox-clip-249439DA.html")))
" ")
("xclip" "-verbose" "-i" "\"/home/ubuntu/My" "Temporary" "Documents/ox-clip-249439DA.html\"" "-t" "text/html" "" "-selection" "clipboard")
etc/NEWS.26:1490:** New optional argument TEXT in 'make-temp-file'.
emacs-25.2 is shipped with Ubuntu-18.04 bionic, so fourth argument does not work for me.
I do not like idea to use shell where simple and robust exec should be enough. Anyway, temporary file likely should be removed even if xclip fails for some reason, so shell commands should be separated by ;
rather than &&
Why are you trying to avoid splitting command into arguments before applying substitution? File names could be tricky. Not so tricky as shell commands, but still... I agree that setting TMPDIR
to some path with quote characters in folder name is shooting a foot, but I am afraid that such code might be copy-pasted to a function where arbitrary directory created by a user could be involved. E.g. find
and xargs
tools (often used together to process a lot of files) have special options to separate file names using null-byte character to safely communicate through a pipe. That allows to handle files with e.g. newlines in their names. Linux kernel system call execve
(that actually executes a binary behind start-process
and make-process
) accept arguments as separate array elements. It is much more safe and reliable to not mix file name with other arguments when it is possible.
Since this issue is not closed, I decided to leave the following comment here.
xclip.el
uses process-send-string
to avoid a temporary file, see
Predictable file name in the
/tmp
directory hardly could be considered as good practice.https://github.com/jkitchin/ox-clip/blob/master/ox-clip.el#L369
There is at least
make-temp-file
function, seeinfo '(elisp)Unique File Names'
, though I do not know if it is the best option.Another system user could create file or symlink with such name causing permission denied error.
Fortunately, nowadays it is at least unlikely a security vulnerability since
fs.protected_symlinks
should be turned on by default.https://www.kernel.org/doc/Documentation/sysctl/fs.txt
P.S. I like the idea to bypass emacs limitations in respect to clipboard format by using an external utility.