From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Patrick Newsgroups: gmane.emacs.help Subject: Re: How can I write this function better? Date: Wed, 15 Mar 2017 10:55:29 +0100 Message-ID: <87o9x2oodq.fsf@rdorte.org> References: <87zigprm7q.fsf@cocaine.ninja> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1489588115 30880 195.159.176.226 (15 Mar 2017 14:28:35 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 15 Mar 2017 14:28:35 +0000 (UTC) User-Agent: mu4e 0.9.18; emacs 24.5.1 To: "help-gnu-emacs\@gnu.org" Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Wed Mar 15 15:28:28 2017 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1co9ua-00078z-0P for geh-help-gnu-emacs@m.gmane.org; Wed, 15 Mar 2017 15:28:24 +0100 Original-Received: from localhost ([::1]:37633 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1co9ug-0001iV-61 for geh-help-gnu-emacs@m.gmane.org; Wed, 15 Mar 2017 10:28:30 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:56292) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1co5ea-0001t2-VI for help-gnu-emacs@gnu.org; Wed, 15 Mar 2017 05:55:38 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1co5eX-0001nE-Te for help-gnu-emacs@gnu.org; Wed, 15 Mar 2017 05:55:37 -0400 Original-Received: from mail-wr0-x22f.google.com ([2a00:1450:400c:c0c::22f]:34600) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1co5eX-0001lt-Ib for help-gnu-emacs@gnu.org; Wed, 15 Mar 2017 05:55:33 -0400 Original-Received: by mail-wr0-x22f.google.com with SMTP id l37so7285419wrc.1 for ; Wed, 15 Mar 2017 02:55:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rdorte-org.20150623.gappssmtp.com; s=20150623; h=references:user-agent:from:to:subject:in-reply-to:date:message-id :mime-version; bh=gyGIdJl/Cs8HuLjNPKqhvKQ1W8WhSPTIO4Fz0j44Zj4=; b=u63YaEg7qUBom3qL4u1pp22nuZcZ+s58JJLjp39s/rwFGzgci/QAeKSQcDLWod0JCN 4XTLNvRsFbLFyrWOKwridDlIU4fJpgk/YBzBNv/HhaxJG57tXT3PR8YSJKBdE64u2utT RbhAkHuJ7zVOWQPtUNbz5hR5aO5LsKwtWK7ETX5LydZbZMAIenq3YTbUaudc2KfMzhcn XIqK1Qogd1cvF0RsnxxFWruOiwNAH5BOUfC8fSS+S2H/rYu11Z4jKABjLIBBfDLLsBqg sUwBmwXIFEmuEZijAbgv2RDXVtdur+8X+Oo4HBio3ho9wpKmgE5roZszA9ecownDdRdj FI4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:references:user-agent:from:to:subject :in-reply-to:date:message-id:mime-version; bh=gyGIdJl/Cs8HuLjNPKqhvKQ1W8WhSPTIO4Fz0j44Zj4=; b=S78DznHD5AVYHKBAXnA6Cf8lIQq/k/6j9RXSF6V0xFdjJD+18OxUVS1MvsYk1nSGP2 UGrpyNj7n+TaXafsZLm358+s8cnOsc1fDkcDxPz0e+o39YdKB3pxcaeH2J5fG3C29s2E OT+1d7u80s+Et4CE4XnNCoZ/UC21C9xbHQEQcrw1FvWjWSClOmgNkAKxsppVYgh8yo4y LCkIGySTBML9M7sgxR0sy8K29dcp0PoWRO64eWVz4gE+C5X0iy9BIAtz8Ppw5+xQV/T0 4PWkWqQWgcBnbq2is9L58RXyFS6bPmznKLLdooQGXs/l9UawtbX9yHXoHC5EqDKDdI6s w1Dw== X-Gm-Message-State: AFeK/H3fWc+RMWMOKBdVOGJ4rC8OlIvCGAbrvnmC+FY+sGZWj3Wk8LjgybXVM27yPf3xjQ== X-Received: by 10.223.172.77 with SMTP id v71mr2456674wrc.131.1489571731677; Wed, 15 Mar 2017 02:55:31 -0700 (PDT) Original-Received: from pmatoe (swsek.klivv.oeaw.ac.at. [193.170.91.5]) by smtp.gmail.com with ESMTPSA id c8sm1692094wrd.34.2017.03.15.02.55.30 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 15 Mar 2017 02:55:30 -0700 (PDT) In-reply-to: X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::22f X-Mailman-Approved-At: Wed, 15 Mar 2017 10:26:22 -0400 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "help-gnu-emacs" Xref: news.gmane.org gmane.emacs.help:112575 Archived-At: On Tue, Mar 14 2017, John Mastro wrote: > user wrote: >> Hello help-gnu-emacs, I'm looking for pointers with my luser-0x0 >> function. I'm sure there are better ways I could write this. I'm not >> asking to have you rewrite it for me, that'd be rude of me, but rather >> what I should to look at, such as documentation or learning new >> constructs etc. I'm _very_ new to programming and Lisp (learning Lisp >> and Forth as my first languages; quite fun). An explanation, which I >> first wrote for myself, is below the code. > > Here was my first thought on how I would personally write it. I wouldn't > say it's better (they achieve the same thing) but perhaps it will give > you an idea or two. > > The things I changed were: > - Make the region beginning and end positions arguments to the function > (which default to the region-or-buffer) when called interactively > - Only call `file-name-extension' when the buffer is visiting a file, > otherwise just use ".txt" > - Call `write-region' directly (rather than via `apply') > - Use `call-process' with a destination buffer rather than > `start-process' with a sentinel > - Delete the temporary file at the end unless an optional argument > says not to > > Regarding the last point, `start-process' does have an advantage, which > is that the process is asynchronous. This attempt takes into account most of these points (but I think that start-process + sentinel is nice for these interactive use cases). I'd also be happy to hear about improvements. (defun hacks/luser-0x0 (buffer &optional start end keep-temp-file) "Upload BUFFER contents to https://0x0.st, maybe only from START to END. If called interactively, it switches to the result buffer when the process has finished. If called from elisp, it returns the process." (interactive (cons (current-buffer) (if (region-active-p) (list (region-beginning) (region-end)) (list (point-min) (point-max))))) (let* ((target (url-generic-parse-url ;; "https://httpbin.org/post" "https://0x0.st")) (tmp-file-name (expand-file-name (concat (make-temp-name "0x0-data") (if (buffer-file-name) (concat "." (or (file-name-extension (buffer-file-name)) "txt")) ".txt") ) temporary-file-directory)) (proc (start-process "curl 0x0" (get-buffer-create (format "* curl 0x0 for %s (copied into %s) *" (buffer-name buffer) tmp-file-name)) "curl" "-F" (format "file=@%s" (with-temp-file tmp-file-name (insert-buffer-substring buffer start end) tmp-file-name)) (url-recreate-url target)))) (process-put proc 'tmp-file tmp-file-name) (process-put proc 'keep-temp-file keep-temp-file) (if (called-interactively-p) (set-process-sentinel proc (lambda (proc event) (cond ((string= event "finished\n") (unless (process-get proc 'keep-temp-file) (delete-file (process-get proc 'tmp-file))) (switch-to-buffer (process-buffer proc)) (message "Process %s finished" (process-name proc))) (t (with-current-buffer (process-buffer proc) (insert event)))))) proc))) It should also allow simultaneous uploads. Note how you can define the process and then add properties or set a sentinel `later' in the function, took me some time to figure this out. But I still don't know if that's always the case (feedback very welcome). The calls to the `url-' functions are not necessary, but I think it's good to know about them. You might also want to look at this very useful tool: https://github.com/pashky/restclient.el. Hope this helps (and happy to hear about improvements), > Regarding the last point, `start-process' does have an advantage, which > is that the process is asynchronous. However, that may not matter for > this, if the upload will proceed quickly and/or you would wait for it to > finish before moving on anyway. For instance, if the upload takes a > while, then it might be odd to have its output added to your kill-ring > at some point later anyway. > > Here's the code (lightly tested): > > (defun luser-0x0 (beg end &optional keep-file) > "Upload region from BEG to END https://0x0.st. > When called interactively, BEG and END default to the bounds of > the region if active, or the buffer otherwise. If KEEP-FILE is > non-nil, do not delete the temporary file that was uploaded." > (interactive > (if (use-region-p) > (list (region-beginning) (region-end)) > (list (point-min) (point-max)))) > (let ((file (make-temp-file "0x0" nil > (if (buffer-file-name) > (file-name-extension (buffer-file-name) t) > ".txt")))) > (write-region beg end file) > (with-temp-buffer > (call-process "curl" nil (current-buffer) nil > "-F" (concat "file=@" file) "https://0x0.st") > (kill-new (message "%s" (buffer-string)))) > (if keep-file > file > (delete-file file t) > nil))) > > Hope that helps > > John -- Patrick