Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!news.albasani.net!feeder.erje.net!newsfeed.xs4all.nl!newsfeed5.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.001 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'python,': 0.01; 'else:': 0.03; 'permissions': 0.04; 'python': 0.08; 'deletion': 0.09; 'finally:': 0.09; 'presume': 0.09; 'def': 0.13; "'w')": 0.16; '-tkc': 0.16; 'f.close()': 0.16; 'from:addr:python.list': 0.16; 'from:addr:tim.thechases.com': 0.16; 'from:name:tim chase': 0.16; 'message-id:@tim.thechases.com': 0.16; 'naming,': 0.16; 'received:70.251': 0.16; 'received:dsl.rcsntx.swbell.net': 0.16; 'received:rcsntx.swbell.net': 0.16; 'received:swbell.net': 0.16; 'temp': 0.16; 'examples': 0.16; 'thanks,': 0.18; 'written': 0.20; '(most': 0.21; 'maybe': 0.21; '(or': 0.22; 'code': 0.25; 'asking': 0.28; 'example': 0.29; 'posts,': 0.30; 'subject:?': 0.31; "i've": 0.31; 'pretty': 0.32; 'header:User-Agent:1': 0.33; 'actually': 0.33; 'rather': 0.33; 'there': 0.33; 'to:addr:python-list': 0.34; 'things': 0.34; 'calling': 0.34; 'anything': 0.34; 'conventions': 0.34; 'try:': 0.34; 'something': 0.35; 'external': 0.35; 'file': 0.36; 'none': 0.37; 'using': 0.38; 'some': 0.38; 'skip:o 20': 0.38; "i'd": 0.39; 'to:addr:python.org': 0.40; 'unique': 0.61; 'efficient': 0.62; 'back': 0.62; 'results': 0.63; 'watch': 0.65; 'are)': 0.84; 'canonical': 0.91; 'conditions,': 0.93; 'subject: $': 0.97 Date: Thu, 22 Dec 2011 22:16:30 -0600 From: Tim Chase User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.24) Gecko/20111120 Icedove/3.1.16 MIME-Version: 1.0 To: Python Subject: Idiom for shelling out to $EDITOR/$PAGER? Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - boston.accountservergroup.com X-AntiAbuse: Original Domain - python.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - tim.thechases.com X-Source: X-Source-Args: X-Source-Dir: X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 53 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1324613800 news.xs4all.nl 6879 [2001:888:2000:d::a6]:36629 X-Complaints-To: abuse@xs4all.nl Xref: x330-a1.tempe.blueboxinc.net comp.lang.python:17772 After a little searching, I've not been able to come up with what I'd consider canonical examples of consider calling an external editor/pager on a file and reading the results back in. (most of my results are swamped by people asking about editors written in Python, or what the best editors for Python code are) The pseudocode would be something like def edit_text(data): temp_fname = generate_temp_name() try: f = file(temp_fname, 'w') f.write(data) f.close() before = info(temp_fname) # maybe stat+checksum? editor = find_sensible_editor() subprocess.call([editor, temp_fname]) if before == info(temp_fname): return None else: return file(temp_fname).read() finally: delete_if_exists(temp_fname) However there are things to watch out for in this lousy code: -race conditions, unique naming, and permissions on the temp file -proper & efficient detection of file-change, to know whether the user actually did anything -cross-platform determination of a sensible editor (that blocks rather than spawns), using platform conventions like os.environ['EDITOR'] -cleanup deletion of the temp-file I presume the code for spawning $PAGER on some content would look pretty similar. Any good example code (or blog posts, or other links) that has been battle-tested? Thanks, -tkc