docs: def _edit_task_config(env, task_config, confirm):
      """ Launches text editor to edit provided task configuration file.
  
          `env`
              Runtime ``Environment`` instance.
          `task_config`
              Path to task configuration file.
  
          `confirm`
              If task config is invalid after edit, prompt to re-edit.
  
          Return boolean.
  
          * Raises ``InvalidTaskConfig`` if edited task config fails to parse
            and `confirm` is ``False``.
          """
  
      # get editor program
      if common.IS_MACOSX:
          def_editor = 'open'
      else:
          def_editor = 'vi'
      editor = os.environ.get('EDITOR', def_editor)
  
      def _edit_file(filename):
          """ Launches editor for given filename.
              """
          proc = subprocess.Popen('{0} {1}'.format(editor, filename),
                                  shell=True)
          proc.communicate()
          if proc.returncode == 0:
              try:
                  # parse temp configuration file
                  parser_ = parser.parse_config(filename, 'task')
                  registration.run_option_hooks(parser_,
                                                disable_missing=False)
  
              except (parser.ParseError, errors.InvalidTaskConfig) as exc:
                  reason = unicode(getattr(exc, 'reason', exc))
                  raise errors.InvalidTaskConfig(task_config, reason=reason)
  
              return True
          else:
              return False
  
      try:
          # create temp copy of task config
          fd, tmpname = tempfile.mkstemp(suffix='.cfg', prefix='focus_')
          with open(task_config, 'r') as file_:
              os.write(fd, file_.read())
              os.close(fd)
  
          while True:
              try:
                  # launch editor
                  if not _edit_file(tmpname):
                      return False
  
                  # overwrite original with temp
                  with open(tmpname, 'r') as temp:
                      with open(task_config, 'w', 0) as config:
                          config.write(temp.read())
  
                  return True
  
              except errors.InvalidTaskConfig as exc:
                  if not confirm:
                      raise  # reraise
  
                  # prompt to re-edit
                  env.io.error(unicode(exc))
                  while True:
                      try:
                          resp = env.io.prompt('Would you like to retry? (y/n) ')
                          resp = resp.strip().lower()
                      except KeyboardInterrupt:
                          return True
  
                      if resp == 'y':
                          break
                      elif resp == 'n':
                          return True
  
      except OSError:
          return False
      finally:
          common.safe_remove_file(tmpname)