Skip to content

Commit

Permalink
Merge branch 'jn/editor-pager'
Browse files Browse the repository at this point in the history
* jn/editor-pager:
  Provide a build time default-pager setting
  Provide a build time default-editor setting
  am -i, git-svn: use "git var GIT_PAGER"
  add -i, send-email, svn, p4, etc: use "git var GIT_EDITOR"
  Teach git var about GIT_PAGER
  Teach git var about GIT_EDITOR
  Suppress warnings from "git var -l"
  Do not use VISUAL editor on dumb terminals
  Handle more shell metacharacters in editor names
  • Loading branch information
gitster committed Nov 21, 2009
2 parents 7a4383c + a3d023d commit 376f39f
Show file tree
Hide file tree
Showing 19 changed files with 178 additions and 69 deletions.
4 changes: 1 addition & 3 deletions Documentation/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,7 @@ core.editor::
Commands such as `commit` and `tag` that lets you edit
messages by launching an editor uses the value of this
variable when it is set, and the environment variable
`GIT_EDITOR` is not set. The order of preference is
`GIT_EDITOR` environment, `core.editor`, `VISUAL` and
`EDITOR` environment variables and then finally `vi`.
`GIT_EDITOR` is not set. See linkgit:git-var[1].

core.pager::
The command that git will use to paginate output. Can
Expand Down
2 changes: 1 addition & 1 deletion Documentation/git-commit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ ENVIRONMENT AND CONFIGURATION VARIABLES
The editor used to edit the commit log message will be chosen from the
GIT_EDITOR environment variable, the core.editor configuration variable, the
VISUAL environment variable, or the EDITOR environment variable (in that
order).
order). See linkgit:git-var[1] for details.

HOOKS
-----
Expand Down
4 changes: 2 additions & 2 deletions Documentation/git-send-email.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ The --bcc option must be repeated for each user you want on the bcc list.
The --cc option must be repeated for each user you want on the cc list.

--compose::
Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
introductory message for the patch series.
Invoke a text editor (see GIT_EDITOR in linkgit:git-var[1])
to edit an introductory message for the patch series.
+
When '--compose' is used, git send-email will use the From, Subject, and
In-Reply-To headers specified in the message. If the body of the message
Expand Down
14 changes: 14 additions & 0 deletions Documentation/git-var.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ GIT_AUTHOR_IDENT::
GIT_COMMITTER_IDENT::
The person who put a piece of code into git.

GIT_EDITOR::
Text editor for use by git commands. The value is meant to be
interpreted by the shell when it is used. Examples: `~/bin/vi`,
`$SOME_ENVIRONMENT_VARIABLE`, `"C:\Program Files\Vim\gvim.exe"
--nofork`. The order of preference is the `$GIT_EDITOR`
environment variable, then `core.editor` configuration, then
`$VISUAL`, then `$EDITOR`, and then finally 'vi'.

GIT_PAGER::
Text viewer for use by git commands (e.g., 'less'). The value
is meant to be interpreted by the shell. The order of preference
is the `$GIT_PAGER` environment variable, then `core.pager`
configuration, then `$PAGER`, and then finally 'less'.

Diagnostics
-----------
You don't exist. Go away!::
Expand Down
28 changes: 28 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,18 @@ all::
# memory allocators with the nedmalloc allocator written by Niall Douglas.
#
# Define NO_REGEX if you have no or inferior regex support in your C library.
#
# Define DEFAULT_PAGER to a sensible pager command (defaults to "less") if
# you want to use something different. The value will be interpreted by the
# shell at runtime when it is used.
#
# Define DEFAULT_EDITOR to a sensible editor command (defaults to "vi") if you
# want to use something different. The value will be interpreted by the shell
# if necessary when it is used. Examples:
#
# DEFAULT_EDITOR='~/bin/vi',
# DEFAULT_EDITOR='$GIT_FALLBACK_EDITOR',
# DEFAULT_EDITOR='"C:\Program Files\Vim\gvim.exe" --nofork'

GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
@$(SHELL_PATH) ./GIT-VERSION-GEN
Expand Down Expand Up @@ -1374,6 +1386,22 @@ BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \
$(COMPAT_CFLAGS)
LIB_OBJS += $(COMPAT_OBJS)

# Quote for C

ifdef DEFAULT_EDITOR
DEFAULT_EDITOR_CQ = "$(subst ",\",$(subst \,\\,$(DEFAULT_EDITOR)))"
DEFAULT_EDITOR_CQ_SQ = $(subst ','\'',$(DEFAULT_EDITOR_CQ))

BASIC_CFLAGS += -DDEFAULT_EDITOR='$(DEFAULT_EDITOR_CQ_SQ)'
endif

ifdef DEFAULT_PAGER
DEFAULT_PAGER_CQ = "$(subst ",\",$(subst \,\\,$(DEFAULT_PAGER)))"
DEFAULT_PAGER_CQ_SQ = $(subst ','\'',$(DEFAULT_PAGER_CQ))

BASIC_CFLAGS += -DDEFAULT_PAGER='$(DEFAULT_PAGER_CQ_SQ)'
endif

ALL_CFLAGS += $(BASIC_CFLAGS)
ALL_LDFLAGS += $(BASIC_LDFLAGS)

Expand Down
2 changes: 2 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,8 @@ extern const char *git_author_info(int);
extern const char *git_committer_info(int);
extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int);
extern const char *fmt_name(const char *name, const char *email);
extern const char *git_editor(void);
extern const char *git_pager(void);

struct checkout {
const char *base_dir;
Expand Down
5 changes: 1 addition & 4 deletions contrib/fast-import/git-p4
Original file line number Diff line number Diff line change
Expand Up @@ -729,13 +729,10 @@ class P4Submit(Command):
tmpFile.write(submitTemplate + separatorLine + diff + newdiff)
tmpFile.close()
mtime = os.stat(fileName).st_mtime
defaultEditor = "vi"
if platform.system() == "Windows":
defaultEditor = "notepad"
if os.environ.has_key("P4EDITOR"):
editor = os.environ.get("P4EDITOR")
else:
editor = os.environ.get("EDITOR", defaultEditor);
editor = read_pipe("git var GIT_EDITOR")
system(editor + " " + fileName)

response = "y"
Expand Down
32 changes: 23 additions & 9 deletions editor.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,38 @@
#include "strbuf.h"
#include "run-command.h"

int launch_editor(const char *path, struct strbuf *buffer, const char *const *env)
#ifndef DEFAULT_EDITOR
#define DEFAULT_EDITOR "vi"
#endif

const char *git_editor(void)
{
const char *editor, *terminal;
const char *editor = getenv("GIT_EDITOR");
const char *terminal = getenv("TERM");
int terminal_is_dumb = !terminal || !strcmp(terminal, "dumb");

editor = getenv("GIT_EDITOR");
if (!editor && editor_program)
editor = editor_program;
if (!editor)
if (!editor && !terminal_is_dumb)
editor = getenv("VISUAL");
if (!editor)
editor = getenv("EDITOR");

terminal = getenv("TERM");
if (!editor && (!terminal || !strcmp(terminal, "dumb")))
return error("Terminal is dumb but no VISUAL nor EDITOR defined.");
if (!editor && terminal_is_dumb)
return NULL;

if (!editor)
editor = DEFAULT_EDITOR;

return editor;
}

int launch_editor(const char *path, struct strbuf *buffer, const char *const *env)
{
const char *editor = git_editor();

if (!editor)
editor = "vi";
return error("Terminal is dumb, but EDITOR unset");

if (strcmp(editor, ":")) {
size_t len = strlen(editor);
Expand All @@ -28,7 +42,7 @@ int launch_editor(const char *path, struct strbuf *buffer, const char *const *en
const char *args[6];
struct strbuf arg0 = STRBUF_INIT;

if (strcspn(editor, "$ \t'") != len) {
if (strcspn(editor, "|&;<>()$`\\\"' \t\n*?[#~=%") != len) {
/* there are specials */
strbuf_addf(&arg0, "%s \"$@\"", editor);
args[i++] = "sh";
Expand Down
3 changes: 1 addition & 2 deletions git-add--interactive.perl
Original file line number Diff line number Diff line change
Expand Up @@ -990,8 +990,7 @@ sub edit_hunk_manually {
EOF
close $fh;

my $editor = $ENV{GIT_EDITOR} || $repo->config("core.editor")
|| $ENV{VISUAL} || $ENV{EDITOR} || "vi";
chomp(my $editor = run_cmd_pipe(qw(git var GIT_EDITOR)));
system('sh', '-c', $editor.' "$@"', $editor, $hunkfile);

if ($? != 0) {
Expand Down
5 changes: 4 additions & 1 deletion git-am.sh
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,10 @@ do
[eE]*) git_editor "$dotest/final-commit"
action=again ;;
[vV]*) action=again
LESS=-S ${PAGER:-less} "$dotest/patch" ;;
: ${GIT_PAGER=$(git var GIT_PAGER)}
: ${LESS=-FRSX}
export LESS
$GIT_PAGER "$dotest/patch" ;;
*) action=again ;;
esac
done
Expand Down
3 changes: 2 additions & 1 deletion git-send-email.perl
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ sub format_2822_time {

# Handle interactive edition of files.
my $multiedit;
my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
my $editor = Git::command_oneline('var', 'GIT_EDITOR');

sub do_edit {
if (defined($multiedit) && !$multiedit) {
map {
Expand Down
19 changes: 6 additions & 13 deletions git-sh-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,12 @@ set_reflog_action() {
}
git_editor() {
: "${GIT_EDITOR:=$(git config core.editor)}"
: "${GIT_EDITOR:=${VISUAL:-${EDITOR}}}"
case "$GIT_EDITOR,$TERM" in
,dumb)
echo >&2 "No editor specified in GIT_EDITOR, core.editor, VISUAL,"
echo >&2 "or EDITOR. Tried to fall back to vi but terminal is dumb."
echo >&2 "Please set one of these variables to an appropriate"
echo >&2 "editor or run $0 with options that will not cause an"
echo >&2 "editor to be invoked (e.g., -m or -F for git-commit)."
exit 1
;;
esac
eval "${GIT_EDITOR:=vi}" '"$@"'
if test -z "${GIT_EDITOR:+set}"
then
GIT_EDITOR="$(git var GIT_EDITOR)" || return $?
fi
eval "$GIT_EDITOR" '"$@"'
}
is_bare_repository () {
Expand Down
11 changes: 4 additions & 7 deletions git-svn.perl
Original file line number Diff line number Diff line change
Expand Up @@ -1332,9 +1332,8 @@ sub get_commit_entry {
close $log_fh or croak $!;

if ($_edit || ($type eq 'tree')) {
my $editor = $ENV{VISUAL} || $ENV{EDITOR} || 'vi';
# TODO: strip out spaces, comments, like git-commit.sh
system($editor, $commit_editmsg);
chomp(my $editor = command_oneline(qw(var GIT_EDITOR)));
system('sh', '-c', $editor.' "$@"', $editor, $commit_editmsg);
}
rename $commit_editmsg, $commit_msg or croak $!;
{
Expand Down Expand Up @@ -5219,10 +5218,8 @@ sub git_svn_log_cmd {

# adapted from pager.c
sub config_pager {
$pager ||= $ENV{GIT_PAGER} || $ENV{PAGER};
if (!defined $pager) {
$pager = 'less';
} elsif (length $pager == 0 || $pager eq 'cat') {
chomp(my $pager = command_oneline(qw(var GIT_PAGER)));
if ($pager eq 'cat') {
$pager = undef;
}
$ENV{GIT_PAGER_IN_USE} = defined($pager);
Expand Down
2 changes: 1 addition & 1 deletion ident.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ const char *fmt_ident(const char *name, const char *email,
if ((warn_on_no_name || error_on_no_name) &&
name == git_default_name && env_hint) {
fprintf(stderr, env_hint, au_env, co_env);
env_hint = NULL; /* warn only once, for "git var -l" */
env_hint = NULL; /* warn only once */
}
if (error_on_no_name)
die("empty ident %s <%s> not allowed", name, email);
Expand Down
24 changes: 20 additions & 4 deletions pager.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
#include "run-command.h"
#include "sigchain.h"

#ifndef DEFAULT_PAGER
#define DEFAULT_PAGER "less"
#endif

/*
* This is split up from the rest of git so that we can do
* something different on Windows.
Expand Down Expand Up @@ -44,12 +48,14 @@ static void wait_for_pager_signal(int signo)
raise(signo);
}

void setup_pager(void)
const char *git_pager(void)
{
const char *pager = getenv("GIT_PAGER");
const char *pager;

if (!isatty(1))
return;
return NULL;

pager = getenv("GIT_PAGER");
if (!pager) {
if (!pager_program)
git_config(git_default_config, NULL);
Expand All @@ -58,8 +64,18 @@ void setup_pager(void)
if (!pager)
pager = getenv("PAGER");
if (!pager)
pager = "less";
pager = DEFAULT_PAGER;
else if (!*pager || !strcmp(pager, "cat"))
pager = NULL;

return pager;
}

void setup_pager(void)
{
const char *pager = git_pager();

if (!pager)
return;

spawned_pager = 1; /* means we are emitting to terminal */
Expand Down
47 changes: 35 additions & 12 deletions t/t7005-editor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,40 @@ test_description='GIT_EDITOR, core.editor, and stuff'

. ./test-lib.sh

for i in GIT_EDITOR core_editor EDITOR VISUAL vi
unset EDITOR VISUAL GIT_EDITOR

test_expect_success 'determine default editor' '
vi=$(TERM=vt100 git var GIT_EDITOR) &&
test -n "$vi"
'

if ! expr "$vi" : '^[a-z]*$' >/dev/null
then
vi=
fi

for i in GIT_EDITOR core_editor EDITOR VISUAL $vi
do
cat >e-$i.sh <<-EOF
#!$SHELL_PATH
echo "Edited by $i" >"\$1"
EOF
chmod +x e-$i.sh
done
unset vi
mv e-vi.sh vi
unset EDITOR VISUAL GIT_EDITOR

if ! test -z "$vi"
then
mv e-$vi.sh $vi
fi

test_expect_success setup '
msg="Hand edited" &&
msg="Hand-edited" &&
test_commit "$msg" &&
echo "$msg" >expect &&
git add vi &&
test_tick &&
git commit -m "$msg" &&
git show -s --pretty=oneline |
sed -e "s/^[0-9a-f]* //" >actual &&
git show -s --format=%s > actual &&
diff actual expect
'
Expand All @@ -42,9 +55,19 @@ test_expect_success 'dumb should error out when falling back on vi' '
fi
'

test_expect_success 'dumb should prefer EDITOR to VISUAL' '
EDITOR=./e-EDITOR.sh &&
VISUAL=./e-VISUAL.sh &&
export EDITOR VISUAL &&
git commit --amend &&
test "$(git show -s --format=%s)" = "Edited by EDITOR"
'

TERM=vt100
export TERM
for i in vi EDITOR VISUAL core_editor GIT_EDITOR
for i in $vi EDITOR VISUAL core_editor GIT_EDITOR
do
echo "Edited by $i" >expect
unset EDITOR VISUAL GIT_EDITOR
Expand All @@ -68,7 +91,7 @@ done

unset EDITOR VISUAL GIT_EDITOR
git config --unset-all core.editor
for i in vi EDITOR VISUAL core_editor GIT_EDITOR
for i in $vi EDITOR VISUAL core_editor GIT_EDITOR
do
echo "Edited by $i" >expect
case "$i" in
Expand Down
Loading

0 comments on commit 376f39f

Please sign in to comment.