Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #17777 > unrolled thread

Re: Idiom for shelling out to $EDITOR/$PAGER?

Started byCameron Simpson <cs@zip.com.au>
First post2011-12-23 17:02 +1100
Last post2011-12-23 21:41 -0500
Articles 6 — 4 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Idiom for shelling out to $EDITOR/$PAGER? Cameron Simpson <cs@zip.com.au> - 2011-12-23 17:02 +1100
    Re: Idiom for shelling out to $EDITOR/$PAGER? Ben Finney <ben+python@benfinney.id.au> - 2011-12-23 17:12 +1100
      Re: Idiom for shelling out to $EDITOR/$PAGER? Cameron Simpson <cs@zip.com.au> - 2011-12-23 17:32 +1100
        Re: Idiom for shelling out to $EDITOR/$PAGER? Ben Finney <ben+python@benfinney.id.au> - 2011-12-23 23:06 +1100
          Re: Idiom for shelling out to $EDITOR/$PAGER? Tim Chase <python.list@tim.thechases.com> - 2011-12-23 06:28 -0600
    Re: Idiom for shelling out to $EDITOR/$PAGER? Owen Jacobson <angrybaldguy@gmail.com> - 2011-12-23 21:41 -0500

#17777 — Re: Idiom for shelling out to $EDITOR/$PAGER?

FromCameron Simpson <cs@zip.com.au>
Date2011-12-23 17:02 +1100
SubjectRe: Idiom for shelling out to $EDITOR/$PAGER?
Message-ID<mailman.4017.1324620143.27778.python-list@python.org>
On 22Dec2011 22:16, Tim Chase <python.list@tim.thechases.com> wrote:
| 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

NamedTemporaryFile is your friend.

| -proper & efficient detection of file-change, to know whether the
| user actually did anything

Wait for the editor to exit?
In that scenario I go for:
  - wait for edit to exit
  - if exit status 0 and file non-empty, trust it
    (subject to parse issues afterwards of course)

| -cross-platform determination of a sensible editor (that blocks
| rather than spawns), using platform conventions like
| os.environ['EDITOR']

os.environment.get('EDITOR', 'vi')?

Some platforms have an executable called "editor" that solves that
problem (absent $EDITOR); MacOSX has "open", though it won't be running
a blocking editor, alas.

You may need some knowledge of the local system. On a terminal? Easy,
use $EDITOR. No terminal, but $DISPLAY? xterm -e "$EDITOR temp_file",
or the like. No terminal, no $DISPLAY, macosx? I have an incantation
somewhere...

| -cleanup deletion of the temp-file

NamedTemporaryFile is your friend.

| I presume the code for spawning $PAGER on some content would look
| pretty similar.

Yep.

| Any good example code (or blog posts, or other links) that has been
| battle-tested?

Hmm. Nothing directly to had, but regarding the temp file:

  # write contents of the file `fp` into a temp file
  with NamedTemporaryFile('w', dir=os.path.join(self.dir, 'tmp')) as T:
    T.write(fp.read())
  ... do stuff with T.name (the temp file name).

Anyway, look it up; it has an autodelete mode etc.

Cheers,
-- 
Cameron Simpson <cs@zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/

I have always been a welly man myself. They are superb in wet grass, let
alone lagoons of pig shit.      - Julian Macassey

[toc] | [next] | [standalone]


#17778

FromBen Finney <ben+python@benfinney.id.au>
Date2011-12-23 17:12 +1100
Message-ID<877h1nn7ej.fsf@benfinney.id.au>
In reply to#17777
Cameron Simpson <cs@zip.com.au> writes:

> On 22Dec2011 22:16, Tim Chase <python.list@tim.thechases.com> wrote:
> | -proper & efficient detection of file-change, to know whether the
> | user actually did anything
>
> Wait for the editor to exit?
> In that scenario I go for:
>   - wait for edit to exit
>   - if exit status 0 and file non-empty, trust it
>     (subject to parse issues afterwards of course)

That doesn't address the concern Tim raised: did the user actually do
anything, did the file change?

The exit status of text editors are not bound to distinguish “buffer was
modified”, and certainly don't do so in any standard way.

My advice:

* Compute a before-edit hash of the text (MD5 or SHA-1 would be fine).

* Invoke the editor on that text.

* Wait for (or detect) the exit of the editor process.

* Compute an after-edit hash of the text resulting from the editor.

* Compare the hashes to see whether the text changed.

-- 
 \       “Come on Milhouse, there's no such thing as a soul! It's just |
  `\      something they made up to scare kids, like the Boogie Man or |
_o__)                          Michael Jackson.” —Bart, _The Simpsons_ |
Ben Finney

[toc] | [prev] | [next] | [standalone]


#17779

FromCameron Simpson <cs@zip.com.au>
Date2011-12-23 17:32 +1100
Message-ID<mailman.4018.1324621939.27778.python-list@python.org>
In reply to#17778
On 23Dec2011 17:12, Ben Finney <ben+python@benfinney.id.au> wrote:
| Cameron Simpson <cs@zip.com.au> writes:
| > On 22Dec2011 22:16, Tim Chase <python.list@tim.thechases.com> wrote:
| > | -proper & efficient detection of file-change, to know whether the
| > | user actually did anything
| >
| > Wait for the editor to exit?
| > In that scenario I go for:
| >   - wait for edit to exit
| >   - if exit status 0 and file non-empty, trust it
| >     (subject to parse issues afterwards of course)
| 
| That doesn't address the concern Tim raised: did the user actually do
| anything, did the file change?

I'm not sure it matters. It's _quicker_ to do nothing if the file is
unchanged, but is it bad to act on it anyway?

| The exit status of text editors are not bound to distinguish “buffer was
| modified”, and certainly don't do so in any standard way.

Indeed not; my 0 above is just "did you user exit the editor or did it
crash"?

| My advice:
| * Compute a before-edit hash of the text (MD5 or SHA-1 would be fine).
| * Invoke the editor on that text.
| * Wait for (or detect) the exit of the editor process.
| * Compute an after-edit hash of the text resulting from the editor.
| * Compare the hashes to see whether the text changed.

Sure. But still, if you're able to act on a changed file, why not also
act on an unchanged file? The user asked to change things; take what you
got back and proceed!

And personally, as a user, I've often rewritten an unchanged file to
force a recompute of something.

Cheers,
-- 
Cameron Simpson <cs@zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/

"Don't you know the speed limit is 55 miles per hour???"
"Yeah, but I wasn't going to be out that long."
        - Steven Wright

[toc] | [prev] | [next] | [standalone]


#17794

FromBen Finney <ben+python@benfinney.id.au>
Date2011-12-23 23:06 +1100
Message-ID<87wr9nlcgk.fsf@benfinney.id.au>
In reply to#17779
Cameron Simpson <cs@zip.com.au> writes:

> On 23Dec2011 17:12, Ben Finney <ben+python@benfinney.id.au> wrote:
> | That doesn't address the concern Tim raised: did the user actually do
> | anything, did the file change?
>
> I'm not sure it matters.

I know of numerous applications where it matters, spcifically ones which
decide what to do with the edited text. Including “submit a bug report”
and “submit a wiki page edit” and “send an email message”.

> Sure. But still, if you're able to act on a changed file, why not also
> act on an unchanged file? The user asked to change things; take what
> you got back and proceed!

If the buffer was not edited, the user has most likely changed their
mind about editing at all, and there are many applications where the
correct default action differes depending on whether the user actually
changed anything in the text.

-- 
 \      “By instructing students how to learn, unlearn, and relearn, a |
  `\         powerful new dimension can be added to education.” —Alvin |
_o__)                                    Toffler, _Future Shock_, 1970 |
Ben Finney

[toc] | [prev] | [next] | [standalone]


#17797

FromTim Chase <python.list@tim.thechases.com>
Date2011-12-23 06:28 -0600
Message-ID<mailman.4028.1324643312.27778.python-list@python.org>
In reply to#17794
On 12/23/11 06:06, Ben Finney wrote:
> Cameron Simpson<cs@zip.com.au>  writes:
>> On 23Dec2011 17:12, Ben Finney<ben+python@benfinney.id.au>
>> wrote: | That doesn't address the concern Tim raised: did
>> the user actually do | anything, did the file change?
>>
>> I'm not sure it matters.
>
> I know of numerous applications where it matters, spcifically
> ones which decide what to do with the edited text. Including
> “submit a bug report” and “submit a wiki page edit” and “send
> an email message”.
>
> If the buffer was not edited, the user has most likely changed
> their mind about editing at all, and there are many
> applications where the correct default action differes
> depending on whether the user actually changed anything in the
> text.

Yes, Ben's understanding is correct here, that for some of my 
use-cases, it's helpful to know if the user did anything.  The 
application can then decide whether it should use the original 
data it passed to the function, or whether it should go some 
"abort what you're doing" route.

-tkc

[toc] | [prev] | [next] | [standalone]


#17831

FromOwen Jacobson <angrybaldguy@gmail.com>
Date2011-12-23 21:41 -0500
Message-ID<2011122321410754142-angrybaldguy@gmailcom>
In reply to#17777
On 2011-12-23 06:02:18 +0000, Cameron Simpson said:

> MacOSX has "open", though it won't be running a blocking editor, alas.

But it can be. From the man page:

     -t  Causes the file to be opened with the default text editor, as deter-
         mined via LaunchServices

and

     -W  Causes open to wait until the applications it opens (or that were
         already open) have exited.  Use with the -n flag to allow open to
         function as an appropriate app for the $EDITOR environment variable.

and finally

     -n  Open a new instance of the application(s) even if one is already run-
         ning.

can be combined to make 'open' (the shell interface to OS X's 
LaunchServices system) into a workable $EDITOR.

-o

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web