# opens a document in editor
# TODO: check no change to document
rlx.edit() {
  local file="${1:-${files[input]}}";
  local output="${2:-${files[document]}}";
  local keep="${3:-false}";
  local changecmd="${4:-}";
  local backup="";
  if [ -f "${output}" ] ;then
    local filename;
    fs.basename "${output}" "filename";
    backup="${directories[backup]}/${filename}";
    cp -f "${output}" "${backup}" \
      || {
        console error -- "backup failed %s" "${output}";
        return 1;
      }
  fi
  local editcmd editoptions;
  if rlx.editable "${output}"; then
    local printoptions=( ${editoptions} );
    rlx.debug "${editcmd} %s" "${printoptions[*]:-}";
    local IFS=$'\n';
    local home="${HOME:-}";
    export USER_HOME="${home}";
    export HOME="${files[user]}";
    $editcmd $editoptions <(cat "${file}");
    local editorcode=$?;
    unset IFS;
    export HOME="${home}";
    unset -v USER_HOME;
    if [ $editorcode -gt 0 ]; then
      console error -- "editor %s exited with %s" \
        "${editcmd}" "${editorcode}";
    else
      if [ ! -f "${output}" ]; then
        console error -- "aborting, document %s not saved" \
          "${output}";
      else
        if [[ "${output}" =~ ${regexp[jsondoc]} ]] && ! lint.execute; then
          rlx.edit.lintfail "$@";
          return 1;
        fi
        if [ -z "${backup}" ]; then
          saved 1;
        elif [ -f "${backup}" ] && [ -f "${output}" ]; then
          cmp -s "${backup}" "${output}" 2>/dev/null;
          saved $?;
        elif [ ! -f "${output}" ]; then
          console error -- "editor error, %s does not exist" "${output}";
        fi
        if [ "${keep}" == false ]; then
          rlx.file.cleanup "${output}";
        fi
        return 0;
      fi
    fi
  else
    console error -- "editor %s is not available" "${editcmd}";
  fi
  return 1;
}

# determine if the editor may be used
rlx.editable() {
  local file="${1}";
  editcmd="${rlx_settings[editor]:-}";
  executable.validate --test "${editcmd}";
  if [ -z "${executables[$editcmd]:-}" ]; then
    return 1;
  fi
  file="$( printf -- %q "${file}" )";
  editoptions=$( printf -- "${rlx_settings[editopts]:-}" "${file}" );
}

rlx.edit.lintfail() {
  local prefix="[lint]";
  accepted() {
    rlx.edit "${output}" "${output}" "${keep}";
    rlx.prompt;
  }
  console prompt --prefix="${prefix}" \
    "invalid json, edit %s? (y/n)" "${output}";
  prompt confirm \
    --accepted=accepted \
    --rejected=rlx.rejected \
    --id=lintfail;
}

# default file saved declaration
document.saved() {
  local changed=$1;
  if [ $changed -gt 0 ]; then
    console ok -- "saved %s" "${output}";
    if method.exists? "$changecmd"; then
      $changecmd;
    fi
  else
    console info -- "no changes %s" "${output}";
  fi
}
