{"thread":{"id":"34906","subject":"[PATCH 2/2] commit: disable status hints when writing to COMMIT_EDITMSG","startedAt":"2013-09-11T09:08:58Z","lastAt":"2013-09-12T09:52:07Z","messageCount":6,"participants":["Matthieu Moy","Eric Sunshine","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"227437","messageId":"1378890539-1966-1-git-send-email-Matthieu.Moy@imag.fr","threadId":"34906","inReplyTo":null,"subject":"[PATCH 1/2] wt-status: turn advice_status_hints into a field of wt_status","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2013-09-11T09:08:58Z","receivedAt":"2013-09-11T09:08:58Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"No behavior change in this patch, but this makes the display of status\nhints more flexible as they can be enabled or disabled for individual\ncalls to commit.c:run_status().\n\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n builtin/commit.c | 10 ++++++++--\n wt-status.c      | 38 +++++++++++++++++++-------------------\n wt-status.h      |  1 +\n 3 files changed, 28 insertions(+), 21 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 60812b5..388acde 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -163,6 +163,12 @@ static void determine_whence(struct wt_status *s)\n \t\ts->whence = whence;\n }\n \n+static void status_finalize(struct wt_status *s)\n+{\n+\tdetermine_whence(s);\n+\ts->hints = advice_status_hints;\n+}\n+\n static void rollback_index_files(void)\n {\n \tswitch (commit_style) {\n@@ -1249,7 +1255,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)\n \twt_status_prepare(&s);\n \tgitmodules_config();\n \tgit_config(git_status_config, &s);\n-\tdetermine_whence(&s);\n+\tstatus_finalize(&s);\n \targc = parse_options(argc, argv, prefix,\n \t\t\t     builtin_status_options,\n \t\t\t     builtin_status_usage, 0);\n@@ -1494,7 +1500,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \tgitmodules_config();\n \tgit_config(git_commit_config, &s);\n \tstatus_format = STATUS_FORMAT_NONE; /* Ignore status.short */\n-\tdetermine_whence(&s);\n+\tstatus_finalize(&s);\n \ts.colopts = 0;\n \n \tif (get_sha1(\"HEAD\", sha1))\ndiff --git a/wt-status.c b/wt-status.c\nindex cb24f1f..885ee66 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -160,7 +160,7 @@ static void wt_status_print_unmerged_header(struct wt_status *s)\n \t\t}\n \t}\n \n-\tif (!advice_status_hints)\n+\tif (!s->hints)\n \t\treturn;\n \tif (s->whence != FROM_COMMIT)\n \t\t;\n@@ -187,7 +187,7 @@ static void wt_status_print_cached_header(struct wt_status *s)\n \tconst char *c = color(WT_STATUS_HEADER, s);\n \n \tstatus_printf_ln(s, c, _(\"Changes to be committed:\"));\n-\tif (!advice_status_hints)\n+\tif (!s->hints)\n \t\treturn;\n \tif (s->whence != FROM_COMMIT)\n \t\t; /* NEEDSWORK: use \"git reset --unresolve\"??? */\n@@ -205,7 +205,7 @@ static void wt_status_print_dirty_header(struct wt_status *s,\n \tconst char *c = color(WT_STATUS_HEADER, s);\n \n \tstatus_printf_ln(s, c, _(\"Changes not staged for commit:\"));\n-\tif (!advice_status_hints)\n+\tif (!s->hints)\n \t\treturn;\n \tif (!has_deleted)\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add <file>...\\\" to update what will be committed)\"));\n@@ -223,7 +223,7 @@ static void wt_status_print_other_header(struct wt_status *s,\n {\n \tconst char *c = color(WT_STATUS_HEADER, s);\n \tstatus_printf_ln(s, c, \"%s:\", what);\n-\tif (!advice_status_hints)\n+\tif (!s->hints)\n \t\treturn;\n \tstatus_printf_ln(s, c, _(\"  (use \\\"git %s <file>...\\\" to include in what will be committed)\"), how);\n \tstatus_printf_ln(s, c, \"\");\n@@ -801,13 +801,13 @@ static void show_merge_in_progress(struct wt_status *s,\n {\n \tif (has_unmerged(s)) {\n \t\tstatus_printf_ln(s, color, _(\"You have unmerged paths.\"));\n-\t\tif (advice_status_hints)\n+\t\tif (s->hints)\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (fix conflicts and run \\\"git commit\\\")\"));\n \t} else {\n \t\tstatus_printf_ln(s, color,\n \t\t\t_(\"All conflicts fixed but you are still merging.\"));\n-\t\tif (advice_status_hints)\n+\t\tif (s->hints)\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (use \\\"git commit\\\" to conclude merge)\"));\n \t}\n@@ -823,7 +823,7 @@ static void show_am_in_progress(struct wt_status *s,\n \tif (state->am_empty_patch)\n \t\tstatus_printf_ln(s, color,\n \t\t\t_(\"The current patch is empty.\"));\n-\tif (advice_status_hints) {\n+\tif (s->hints) {\n \t\tif (!state->am_empty_patch)\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (fix conflicts and then run \\\"git am --continue\\\")\"));\n@@ -896,7 +896,7 @@ static void show_rebase_in_progress(struct wt_status *s,\n \t\telse\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t\t _(\"You are currently rebasing.\"));\n-\t\tif (advice_status_hints) {\n+\t\tif (s->hints) {\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (fix conflicts and then run \\\"git rebase --continue\\\")\"));\n \t\t\tstatus_printf_ln(s, color,\n@@ -913,7 +913,7 @@ static void show_rebase_in_progress(struct wt_status *s,\n \t\telse\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t\t _(\"You are currently rebasing.\"));\n-\t\tif (advice_status_hints)\n+\t\tif (s->hints)\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (all conflicts fixed: run \\\"git rebase --continue\\\")\"));\n \t} else if (split_commit_in_progress(s)) {\n@@ -925,7 +925,7 @@ static void show_rebase_in_progress(struct wt_status *s,\n \t\telse\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t\t _(\"You are currently splitting a commit during a rebase.\"));\n-\t\tif (advice_status_hints)\n+\t\tif (s->hints)\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (Once your working directory is clean, run \\\"git rebase --continue\\\")\"));\n \t} else {\n@@ -937,7 +937,7 @@ static void show_rebase_in_progress(struct wt_status *s,\n \t\telse\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t\t _(\"You are currently editing a commit during a rebase.\"));\n-\t\tif (advice_status_hints && !s->amend) {\n+\t\tif (s->hints && !s->amend) {\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (use \\\"git commit --amend\\\" to amend the current commit)\"));\n \t\t\tstatus_printf_ln(s, color,\n@@ -952,7 +952,7 @@ static void show_cherry_pick_in_progress(struct wt_status *s,\n \t\t\t\t\tconst char *color)\n {\n \tstatus_printf_ln(s, color, _(\"You are currently cherry-picking.\"));\n-\tif (advice_status_hints) {\n+\tif (s->hints) {\n \t\tif (has_unmerged(s))\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (fix conflicts and run \\\"git cherry-pick --continue\\\")\"));\n@@ -971,7 +971,7 @@ static void show_revert_in_progress(struct wt_status *s,\n {\n \tstatus_printf_ln(s, color, _(\"You are currently reverting commit %s.\"),\n \t\t\t find_unique_abbrev(state->revert_head_sha1, DEFAULT_ABBREV));\n-\tif (advice_status_hints) {\n+\tif (s->hints) {\n \t\tif (has_unmerged(s))\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (fix conflicts and run \\\"git revert --continue\\\")\"));\n@@ -995,7 +995,7 @@ static void show_bisect_in_progress(struct wt_status *s,\n \telse\n \t\tstatus_printf_ln(s, color,\n \t\t\t\t _(\"You are currently bisecting.\"));\n-\tif (advice_status_hints)\n+\tif (s->hints)\n \t\tstatus_printf_ln(s, color,\n \t\t\t_(\"  (use \\\"git bisect reset\\\" to get back to the original branch)\"));\n \twt_status_print_trailer(s);\n@@ -1233,7 +1233,7 @@ void wt_status_print(struct wt_status *s)\n \t\t}\n \t} else if (s->commitable)\n \t\tstatus_printf_ln(s, GIT_COLOR_NORMAL, _(\"Untracked files not listed%s\"),\n-\t\t\tadvice_status_hints\n+\t\t\ts->hints\n \t\t\t? _(\" (use -u option to show untracked files)\") : \"\");\n \n \tif (s->verbose)\n@@ -1244,25 +1244,25 @@ void wt_status_print(struct wt_status *s)\n \t\telse if (s->nowarn)\n \t\t\t; /* nothing */\n \t\telse if (s->workdir_dirty) {\n-\t\t\tif (advice_status_hints)\n+\t\t\tif (s->hints)\n \t\t\t\tprintf(_(\"no changes added to commit \"\n \t\t\t\t\t \"(use \\\"git add\\\" and/or \\\"git commit -a\\\")\\n\"));\n \t\t\telse\n \t\t\t\tprintf(_(\"no changes added to commit\\n\"));\n \t\t} else if (s->untracked.nr) {\n-\t\t\tif (advice_status_hints)\n+\t\t\tif (s->hints)\n \t\t\t\tprintf(_(\"nothing added to commit but untracked files \"\n \t\t\t\t\t \"present (use \\\"git add\\\" to track)\\n\"));\n \t\t\telse\n \t\t\t\tprintf(_(\"nothing added to commit but untracked files present\\n\"));\n \t\t} else if (s->is_initial) {\n-\t\t\tif (advice_status_hints)\n+\t\t\tif (s->hints)\n \t\t\t\tprintf(_(\"nothing to commit (create/copy files \"\n \t\t\t\t\t \"and use \\\"git add\\\" to track)\\n\"));\n \t\t\telse\n \t\t\t\tprintf(_(\"nothing to commit\\n\"));\n \t\t} else if (!s->show_untracked_files) {\n-\t\t\tif (advice_status_hints)\n+\t\t\tif (s->hints)\n \t\t\t\tprintf(_(\"nothing to commit (use -u to show untracked files)\\n\"));\n \t\t\telse\n \t\t\t\tprintf(_(\"nothing to commit\\n\"));\ndiff --git a/wt-status.h b/wt-status.h\nindex fb7152e..b4c9cb4 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -59,6 +59,7 @@ struct wt_status {\n \tunsigned colopts;\n \tint null_termination;\n \tint show_branch;\n+\tint hints;\n \n \t/* These are computed during processing of the individual sections */\n \tint commitable;\n-- \n1.8.4.8.g834017f\n"},{"id":"227436","messageId":"1378890539-1966-2-git-send-email-Matthieu.Moy@imag.fr","threadId":"34906","inReplyTo":"1378890539-1966-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH 2/2] commit: disable status hints when writing to COMMIT_EDITMSG","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2013-09-11T09:08:59Z","receivedAt":"2013-09-11T09:08:59Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"This turns the template COMMIT_EDITMSG from e.g\n\n  # [...]\n  # Changes to be committed:\n  #   (use \"git reset HEAD <file>...\" to unstage)\n  #\n  #\tmodified:   builtin/commit.c\n  #\n  # Untracked files:\n  #   (use \"git add <file>...\" to include in what will be committed)\n  #\n  #\tt/foo\n  #\n\nto\n\n  # [...]\n  # Changes to be committed:\n  #\tmodified:   builtin/commit.c\n  #\n  # Untracked files:\n  #\tt/foo\n  #\n\nMost status hints were written to be accurate when running \"git status\"\nbefore running a commit. Many of them are not applicable when the commit\nhas already been started, and should not be shown in COMMIT_EDITMSG. The\nmost obvious are hints advising to run \"git commit\",\n\"git rebase/am/cherry-pick --continue\", which do not make sense when the\ncommand has already been ran.\n\nOther messages become slightly inaccurate (e.g. hint to use \"git add\" to\nadd untracked files), as the suggested commands are not immediately\napplicable during the edition of COMMIT_EDITMSG, but would be applicable\nif the commit is aborted. These messages are both potentially helpful and\nslightly misleading. This patch chose to remove them too, to avoid\nintroducing too much complexity in the status code.\n\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\nJunio, you'll get a trivial merge conflict with my other status\nseries, as they both add a few lines of code at the same location.\nThere should be no semantic conflict so I didn't consider the branches\nas dependant.\n\n\n builtin/commit.c | 6 ++++++\n 1 file changed, 6 insertions(+)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 388acde..6251d29 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -702,6 +702,12 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \tif (s->fp == NULL)\n \t\tdie_errno(_(\"could not open '%s'\"), git_path(commit_editmsg));\n \n+\t/*\n+\t * Most hints are counter-productive when the commit has\n+\t * already started.\n+\t */\n+\ts->hints = 0;\n+\n \tif (clean_message_contents)\n \t\tstripspace(&sb, 0);\n \n-- \n1.8.4.8.g834017f\n"},{"id":"227438","messageId":"CAPig+cRfgSrSMHT0OX0H=uh-Wi3TceU+UN8gUH4La1RTpRLETQ@mail.gmail.com","threadId":"34906","inReplyTo":"1378890539-1966-2-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH 2/2] commit: disable status hints when writing to COMMIT_EDITMSG","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2013-09-11T09:13:05Z","receivedAt":"2013-09-11T09:13:05Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Sep 11, 2013 at 5:08 AM, Matthieu Moy <Matthieu.Moy@imag.fr> wrote:\n> Most status hints were written to be accurate when running \"git status\"\n> before running a commit. Many of them are not applicable when the commit\n> has already been started, and should not be shown in COMMIT_EDITMSG. The\n> most obvious are hints advising to run \"git commit\",\n> \"git rebase/am/cherry-pick --continue\", which do not make sense when the\n> command has already been ran.\n\ns/ran/run/\n\n> Other messages become slightly inaccurate (e.g. hint to use \"git add\" to\n> add untracked files), as the suggested commands are not immediately\n> applicable during the edition of COMMIT_EDITMSG, but would be applicable\n\ns/edition/editing/\n\n> if the commit is aborted. These messages are both potentially helpful and\n> slightly misleading. This patch chose to remove them too, to avoid\n> introducing too much complexity in the status code.\n>\n> Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n"},{"id":"227479","messageId":"20130911183519.GA24251@sigill.intra.peff.net","threadId":"34906","inReplyTo":"1378890539-1966-1-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH 1/2] wt-status: turn advice_status_hints into a field of wt_status","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2013-09-11T18:35:20Z","receivedAt":"2013-09-11T18:35:20Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Sep 11, 2013 at 11:08:58AM +0200, Matthieu Moy wrote:\n\n> No behavior change in this patch, but this makes the display of status\n> hints more flexible as they can be enabled or disabled for individual\n> calls to commit.c:run_status().\n> [...]\n> +static void status_finalize(struct wt_status *s)\n> +{\n> +\tdetermine_whence(s);\n> +\ts->hints = advice_status_hints;\n> +}\n\nIs a \"finalize\" the right place to put the status hint tweak? I would\nexpect the order for callers to be:\n\n  wt_status_prepare(&s);\n  /* manual tweaks of fields in \"s\" */\n  wt_status_finalize(&s);\n\nbut the finalize would overwrite any tweak of the hints field. So it\nwould make more sense to me for it to go in prepare().\n\nBut the current callsites look like this:\n\n> @@ -1249,7 +1255,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)\n>  \twt_status_prepare(&s);\n>  \tgitmodules_config();\n>  \tgit_config(git_status_config, &s);\n> -\tdetermine_whence(&s);\n> +\tstatus_finalize(&s);\n>  \targc = parse_options(argc, argv, prefix,\n>  \t\t\t     builtin_status_options,\n>  \t\t\t     builtin_status_usage, 0);\n\nWe do not actually read the config until after _prepare, because the\nconfig is what is doing the tweaking of \"s\" in this case. But we cannot\ntrust advice_* until we have read the config.\n\nThe problem is that we are doing two things in that git_config call:\n\n  1. Loading basic git-wide core config.\n\n  2. Priming the wt_status struct with options specific to \"git status\"\n\nSo the \"cleanest\" thing would be something like:\n\n  /* load basic config */\n  git_config(git_diff_ui_config, NULL);\n\n  /* initialize the status-run struct; this would probably be better named as\n   * _init to match the rest of the code */\n  wt_status_prepare(&s);\n\n  /* now tweak the defaults using status-specific config, which does\n   * not need to chain to other config callbacks anymore */\n  git_config(git_status_config, &s);\n\n  /* and then tweak further with command line options */\n  argc = parse_options(...);\n\n  /* and now finally ask wt-status to finalize any setup we've put into\n     the struct (e.g., calling determine_whence, though I do not\n     actually see it depending on any of the fields we set. Should it\n     be part of _prepare? */\n  wt_status_finalize(&s);\n\n\nThat would follow our more usual object init-tweak-finalize-use\npatterns. Hrm. To make matters more complicated, we have\nfinalize_deferred_config, too. I think that could be rolled into\nwt_status_finalize.\n\nPerhaps that is getting a bit complicated as a refactor. If you don't\nwant to do it, I understand, but I think you should probably avoid the\nname \"_finalize\" here, as it is a bit mis-leading.\n\n-Peff\n"},{"id":"227518","messageId":"vpqeh8u1iip.fsf@anie.imag.fr","threadId":"34906","inReplyTo":"20130911183519.GA24251@sigill.intra.peff.net","subject":"Re: [PATCH 1/2] wt-status: turn advice_status_hints into a field of wt_status","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2013-09-12T09:44:30Z","receivedAt":"2013-09-12T09:44:30Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Wed, Sep 11, 2013 at 11:08:58AM +0200, Matthieu Moy wrote:\n>\n>> No behavior change in this patch, but this makes the display of status\n>> hints more flexible as they can be enabled or disabled for individual\n>> calls to commit.c:run_status().\n>> [...]\n>> +static void status_finalize(struct wt_status *s)\n>> +{\n>> +\tdetermine_whence(s);\n>> +\ts->hints = advice_status_hints;\n>> +}\n>\n> Is a \"finalize\" the right place to put the status hint tweak? I would\n> expect the order for callers to be:\n>\n>   wt_status_prepare(&s);\n>   /* manual tweaks of fields in \"s\" */\n>   wt_status_finalize(&s);\n>\n> but the finalize would overwrite any tweak of the hints field. So it\n> would make more sense to me for it to go in prepare().\n\n\"finalize\" is indeed not the right name. I made a separate function to\navoid too much code duplication between status and commit, and looked\nfor a name comlementary to \"prepare\" for a function that is ran later to\nfill-in some fields.\n\n> The problem is that we are doing two things in that git_config call:\n>\n>   1. Loading basic git-wide core config.\n\n(Yes. This includes the advice section, so I need it for\nadvice_status_hints)\n\n> So the \"cleanest\" thing would be something like:\n>\n>   git_config(git_diff_ui_config, NULL);\n>   wt_status_prepare(&s);\n\n[...]\n\nThat is clean, but a bit long and it is essentially duplicated between\nstatus and commit. I went another way: put all the similar code in a\ncommon function status_init_config:\n\nstatic void status_init_config(struct wt_status *s, config_fn_t fn)\n{\n\twt_status_prepare(s);\n\tgitmodules_config();\n\tgit_config(git_status_config, s);\n\tdetermine_whence(s);\n\ts->hints = advice_status_hints; /* must come after git_config() */\n}\n\nWe could split the git_config call, but that would not bring much\nbenefit IMHO. In any case, it can be done very simply on top of my patch\nif needed later, as there is now only one call site for git_config.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"227519","messageId":"20130912095207.GA31493@sigill.intra.peff.net","threadId":"34906","inReplyTo":"vpqeh8u1iip.fsf@anie.imag.fr","subject":"Re: [PATCH 1/2] wt-status: turn advice_status_hints into a field of wt_status","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2013-09-12T09:52:07Z","receivedAt":"2013-09-12T09:52:07Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Sep 12, 2013 at 11:44:30AM +0200, Matthieu Moy wrote:\n\n> That is clean, but a bit long and it is essentially duplicated between\n> status and commit. I went another way: put all the similar code in a\n> common function status_init_config:\n> \n> static void status_init_config(struct wt_status *s, config_fn_t fn)\n> {\n> \twt_status_prepare(s);\n> \tgitmodules_config();\n> \tgit_config(git_status_config, s);\n> \tdetermine_whence(s);\n> \ts->hints = advice_status_hints; /* must come after git_config() */\n> }\n\ns/git_status_config/fn/, I assume.\n\n> We could split the git_config call, but that would not bring much\n> benefit IMHO. In any case, it can be done very simply on top of my patch\n> if needed later, as there is now only one call site for git_config.\n\nYeah, I think that is fine. The other cleanup may or may not be worth\nit, but should not be a blocker to your patch. With what you suggest\nabove, you are certainly not making anything worse with respect to the\ncode organization.\n\nThanks.\n\n-Peff\n"}]}