From 222e36ee3e969bb944e49bf38ce1744f5e36c549 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Thu, 25 Jul 2013 15:05:09 +0200 Subject: [PATCH 001/170] Fix make command completion. Fixes issue #928. Previously, TAB on make CC=/us caused CC=/us/usr/ to appear. This commit fixes this, by properly removing part after equals sign. --- share/completions/make.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/completions/make.fish b/share/completions/make.fish index 05845e10d..dfe5090a4 100644 --- a/share/completions/make.fish +++ b/share/completions/make.fish @@ -6,7 +6,7 @@ # complicated to do. set -l is_assignment "commandline -ct|sgrep '..*='" -set -l complete_file_assignment '(commandline -ct)(complete --do-complete=this_command_does_not_exist\ (commandline -ct|sed -e \'s/.*=//\'))' +set -l complete_file_assignment '(commandline -ct|sed -e \'s/=.*/=/\')(complete --do-complete=this_command_does_not_exist\ (commandline -ct|sed -e \'s/.*=//\'))' complete -c make --condition $is_assignment -a $complete_file_assignment complete -x -c make -a "(__fish_print_make_targets)" --description "Target" From 31b01f8de338ae4a5f055f4e589aa440bee9e893 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Tue, 2 Jul 2013 11:08:20 -0400 Subject: [PATCH 002/170] git_prompt: Reorder show_upstream to match original This makes it easier to see if there are any changes. Also it puts all of the extra functionality together instead of mixed in with everything else. --- share/functions/__fish_git_prompt.fish | 35 +++++++++++++++----------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index ea4df57a4..b36aa052d 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -78,30 +78,36 @@ set -g ___fish_git_prompt_status_order stagedstate invalidstate dirtystate untrackedfiles function __fish_git_prompt_show_upstream --description "Helper function for __fish_git_prompt" - # Ask git-config for some config options - set -l svn_remote - set -l svn_prefix + set -l show_upstream $__fish_git_prompt_showupstream + set -l svn_prefix # For better SVN upstream information + set -l informative + + set -l svn_url_pattern + set -l count set -l upstream git set -l legacy set -l verbose - set -l informative - set -l svn_url_pattern - set -l show_upstream $__fish_git_prompt_showupstream - git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showUpstream)$' ^/dev/null | tr '\0\n' '\n ' | while read -l key value + + set -l svn_remote + # get some config options from git-config + git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' ^/dev/null | tr '\0\n' '\n ' | while read -l key value switch $key - case bash.showUpstream bash.showupstream + case bash.showupstream set show_upstream $value test -n "$show_upstream"; or return case svn-remote.'*'.url set svn_remote $svn_remote $value - set -l remote_prefix (/bin/sh -c 'echo "${1%.url}"' -- $key) - set svn_prefix $svn_prefix $remote_prefix + # Avoid adding \| to the beginning to avoid needing #?? later if test -n "$svn_url_pattern" - set svn_url_pattern $svn_url_pattern"\|$value" + set svn_url_pattern $svn_url_pattern"\\|$value" else set svn_url_pattern $value end set upstream svn+git # default upstream is SVN if available, else git + + # Save the config key (without .url) for later use + set -l remote_prefix (/bin/sh -c 'echo "${1%.url}"' -- $key) + set svn_prefix $svn_prefix $remote_prefix end end @@ -151,6 +157,8 @@ function __fish_git_prompt_show_upstream --description "Helper function for __fi end else set upstream (/bin/sh -c 'val=${1#/branches}; echo "${val#/}"' -- $svn_upstream) + + # Use fetch config to fix upstream set -l fetch_val (git config "$cur_prefix".fetch) if test -n "$fetch_val" set -l IFS : @@ -158,13 +166,12 @@ function __fish_git_prompt_show_upstream --description "Helper function for __fi set upstream (/bin/sh -c 'echo "${1%/$2}"' -- $pattern $trunk)/$upstream end end - else if test $upstream = svn+git + else if test $upstream = svn+git set upstream '@{upstream}' end end # Find how many commits we are ahead/behind our upstream - set -l count if test -z "$legacy" set count (git rev-list --count --left-right $upstream...HEAD ^/dev/null) else @@ -238,7 +245,6 @@ function __fish_git_prompt --description "Prompt function for Git" __fish_git_prompt_validate_chars if test "true" = (git rev-parse --is-inside-work-tree ^/dev/null) - if test -n "$__fish_git_prompt_show_informative_status" set informative_status "|"(__fish_git_prompt_informative_status) else @@ -265,7 +271,6 @@ function __fish_git_prompt --description "Prompt function for Git" if test -n "$__fish_git_prompt_showupstream" set p (__fish_git_prompt_show_upstream) end - end __fish_git_prompt_validate_colors From 5753fa2106688115802eaae79005e1ec87f309e9 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Tue, 2 Jul 2013 11:15:34 -0400 Subject: [PATCH 003/170] git_prompt: Merge operation, branch, and bare helpers Operation and branch detection are merged together in the original because branch information may come from different places depending on the operation. Merging the bare helper in helps avoid testing for the working directory and bare status twice, both of which requires forking a new process. Also helps the code match the original more, which will make adding new features easier. --- share/functions/__fish_git_prompt.fish | 90 ++++++++++++-------------- 1 file changed, 41 insertions(+), 49 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index b36aa052d..84ce09017 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -232,13 +232,14 @@ function __fish_git_prompt --description "Prompt function for Git" set -l git_dir (__fish_git_prompt_git_dir) test -n "$git_dir"; or return - set -l r (__fish_git_prompt_current_operation $git_dir) - set -l b (__fish_git_prompt_current_branch $git_dir) + set -l rbc (__fish_git_prompt_operation_branch_bare $git_dir) + set -l r $rbc[1] # current operation + set -l b $rbc[2] # current branch set -l w #dirty working directory set -l i #staged changes set -l s #stashes set -l u #untracked - set -l c (__fish_git_prompt_current_branch_bare) + set -l c $rbc[3] # bare repository set -l p #upstream set -l informative_status @@ -379,56 +380,14 @@ function __fish_git_prompt_informative_status end -function __fish_git_prompt_current_branch_bare --description "__fish_git_prompt helper, tells wheter or not the current branch is bare" - set -l bare - - if test "true" = (git rev-parse --is-inside-git-dir ^/dev/null) - if test "true" = (git rev-parse --is-bare-repository ^/dev/null) - set bare "BARE:" - end - end - echo $bare -end - -function __fish_git_prompt_current_branch --description "__fish_git_prompt helper, returns the current Git branch" +# Keeping these together avoids many duplicated checks +function __fish_git_prompt_operation_branch_bare --description "__fish_git_prompt helper, returns the current Git operation and branch" set -l git_dir $argv[1] set -l branch - - set -l os - set branch (git symbolic-ref HEAD ^/dev/null; set os $status) - if test $os -ne 0 - set branch (switch "$__fish_git_prompt_describe_style" - case contains - git describe --contains HEAD - case branch - git describe --contains --all HEAD - case describe - git describe HEAD - case default '*' - git describe --tags --exact-match HEAD - end ^/dev/null; set os $status) - if test $os -ne 0 - set branch (cut -c1-7 $git_dir/HEAD ^/dev/null; set os $status) - if test $os -ne 0 - set branch unknown - end - end - set branch "($branch)" - end - - # Let user know they're inside the git dir of a non-bare repo - if test "true" = (git rev-parse --is-inside-git-dir ^/dev/null) - if test "false" = (git rev-parse --is-bare-repository ^/dev/null) - set branch "GIT_DIR!" - end - end - echo $branch -end - -function __fish_git_prompt_current_operation --description "__fish_git_prompt helper, returns the current Git operation being performed" set -l operation + set -l bare + set -l os - set -l git_dir $argv[1] if test -f $git_dir/rebase-merge/interactive set operation "|REBASE-i" else if test -d $git_dir/rebase-merge @@ -450,7 +409,40 @@ function __fish_git_prompt_current_operation --description "__fish_git_prompt he set operation "|BISECTING" end end + + set branch (git symbolic-ref HEAD ^/dev/null; set os $status) + if test $os -ne 0 + set branch (switch "$__fish_git_prompt_describe_style" + case contains + git describe --contains HEAD + case branch + git describe --contains --all HEAD + case describe + git describe HEAD + case default '*' + git describe --tags --exact-match HEAD + end ^/dev/null; set os $status) + if test $os -ne 0 + set branch (cut -c1-7 $git_dir/HEAD ^/dev/null; set os $status) + if test $os -ne 0 + set branch unknown + end + end + set branch "($branch)" + end + + if test "true" = (git rev-parse --is-inside-git-dir ^/dev/null) + if test "true" = (git rev-parse --is-bare-repository ^/dev/null) + set bare "BARE:" + else + # Let user know they're inside the git dir of a non-bare repo + set branch "GIT_DIR!" + end + end + echo $operation + echo $branch + echo $bare end function __fish_git_prompt_git_dir --description "__fish_git_prompt helper, returns .git dir if any" From d5c1bf98d7d49d214bbf500d004d96ef2df77b60 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Tue, 2 Jul 2013 11:16:11 -0400 Subject: [PATCH 004/170] git_prompt: Add branch information for rebase --- share/functions/__fish_git_prompt.fish | 35 +++++++++++++++----------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 84ce09017..e39b2c1a2 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -390,8 +390,10 @@ function __fish_git_prompt_operation_branch_bare --description "__fish_git_promp if test -f $git_dir/rebase-merge/interactive set operation "|REBASE-i" + set branch (cat $git_dir/rebase-merge/head-name ^/dev/null) else if test -d $git_dir/rebase-merge set operation "|REBASE-m" + set branch (cat $git_dir/rebase-merge/head-name ^/dev/null) else if test -d $git_dir/rebase-apply if test -f $git_dir/rebase-apply/rebasing @@ -410,25 +412,28 @@ function __fish_git_prompt_operation_branch_bare --description "__fish_git_promp end end - set branch (git symbolic-ref HEAD ^/dev/null; set os $status) - if test $os -ne 0 - set branch (switch "$__fish_git_prompt_describe_style" - case contains - git describe --contains HEAD - case branch - git describe --contains --all HEAD - case describe - git describe HEAD - case default '*' - git describe --tags --exact-match HEAD - end ^/dev/null; set os $status) + if test -z "$branch" + set branch (git symbolic-ref HEAD ^/dev/null; set os $status) if test $os -ne 0 - set branch (cut -c1-7 $git_dir/HEAD ^/dev/null; set os $status) + set detached yes + set branch (switch "$__fish_git_prompt_describe_style" + case contains + git describe --contains HEAD + case branch + git describe --contains --all HEAD + case describe + git describe HEAD + case default '*' + git describe --tags --exact-match HEAD + end ^/dev/null; set os $status) if test $os -ne 0 - set branch unknown + set branch (cut -c1-7 $git_dir/HEAD ^/dev/null; set os $status) + if test $os -ne 0 + set branch unknown + end end + set branch "($branch)" end - set branch "($branch)" end if test "true" = (git rev-parse --is-inside-git-dir ^/dev/null) From 0af49d0533adc80de76660cc6e5972c34fc49fde Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Tue, 2 Jul 2013 11:10:15 -0400 Subject: [PATCH 005/170] git_prompt: Update documentation * The original __git_ps1 function has split from the rest of git-completion as of git.git af31a45 * Use the description for GIT_PS1_DESCRIBE_STYLE (added in git.git 50b03b0) for __fish_git_prompt_describe_style * Update the description of __fish_git_prompt_showupstream to include the meaning of '=' based on git.git f9db192: "Improve the description of GIT_PS1_SHOWUPSTREAM" * Note that the PROMPT_COMMAND versions of the command with extra arguments don't work, in case someone used to the bash version is looking for it. * Note that I am updating the script so Kevin Ballard doesn't get blamed for anything I break. --- share/functions/__fish_git_prompt.fish | 38 ++++++++++++++++---------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index e39b2c1a2..c1da923de 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -1,13 +1,14 @@ -# based off of the git-completion script that ships with git +# based off of the git-prompt script that ships with git # # Written by Kevin Ballard +# Updated by Brian Gernhardt # -# This is heavily based off of the git-completion.bash script that ships with +# This is heavily based off of the git-prompt.bash script that ships with # git, which is Copyright (C) 2006,2007 Shawn O. Pearce . # The act of porting the code, along with any new code, are Copyright (C) 2012 # Kevin Ballard . # -# By virtue of being based on the git-completion.bash script, this script is +# By virtue of being based on the git-prompt.bash script, this script is # distributed under the GNU General Public License, version 2.0. # # This script vends a function __fish_git_prompt which takes a format string, @@ -15,18 +16,14 @@ # function. # # The behavior of __fish_git_prompt is very heavily based off of the bash -# script's __fish_git_prompt function. As such, usage and customization is very +# script's __git_ps1 function. As such, usage and customization is very # similar, although some extra flexibility is provided in this script. +# Due to differences between bash and fish, the PROMPT_COMMAND style where +# passing two or three arguments causes the fucnction to set PS1 is not +# supported. # # The argument to __fish_git_prompt will be displayed only if you are currently -# in a git repository. The %s token will be the name of the branch. If HEAD is -# not a branch, it attempts to show the relevant tag. The tag search is -# controlled by the __fish_git_prompt_describe_style variable, with the -# following values: -# default (or unset) Any tag that exactly matches HEAD -# contains Nearest annotated tag that contains HEAD -# branch Nearest tag/branch that contains HEAD -# describe Output of `git describe` +# in a git repository. The %s token will be the name of the branch. # # In addition, if you set __fish_git_prompt_showdirtystate to a nonempty value, # unstaged (*) and staged (+) changes will be shown next to the branch name. @@ -45,20 +42,31 @@ # # If you would like to see the difference between HEAD and its upstream, set # __fish_git_prompt_showupstream to 'auto'. A "<" indicates you are behind, ">" -# indicates you are ahead, and "<>" indicates you have diverged. You can -# further control behavior by setting __fish_git_prompt_showupstream to a -# space-separated list of values: +# indicates you are ahead, "<>" indicates you have diverged and "=" indicates +# that there is no difference. You can further control behavior by setting +# __fish_git_prompt_showupstream to a space-separated list of values: +# # verbose show number of commits head/behind (+/-) upstream # legacy don't use the '--count' option available in recent versions # of git-rev-list # git always compare HEAD to @{upstream} # svn always compare HEAD to your SVN upstream +# # By default, __fish_git_prompt will compare HEAD to your SVN upstream if it # can find one, or @{upstream} otherwise. Once you have set # __fish_git_prompt_showupstream, you can override it on a per-repository basis # by setting the bash.showUpstream config variable. As before, this variable # remains named 'bash' to preserve compatibility. # +# If you would like to see more information about the identity of commits +# checked out as a detached HEAD, set __fish_git_prompt_describe_style to +# one of the following values: +# +# contains relative to newer annotated tag (v1.6.3.2~35) +# branch relative to newer tag or branch (master~4) +# describe relative to older annotated tag (v1.6.3.1-13-gdd42c2f) +# default exactly matching tag +# # This fish-compatible version of __fish_git_prompt includes some additional # features on top of the above-documented bash-compatible features: # From 3fe1adfc6de719926c9b7b73d6e5932d2c6d16d0 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Tue, 2 Jul 2013 12:40:45 -0400 Subject: [PATCH 006/170] git_prompt: Expand color/character explinations This will be getting more complicated when I add the showcolorhint option from git.git. --- share/functions/__fish_git_prompt.fish | 41 +++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index c1da923de..ee6b1103e 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -70,18 +70,39 @@ # This fish-compatible version of __fish_git_prompt includes some additional # features on top of the above-documented bash-compatible features: # -# The color for the branch name and each individual optional component can be -# specified using __fish_git_prompt_color_, where is 'prefix', -# 'suffix', 'bare', 'merging', 'branch', 'dirtystate', 'stagedstate', -# 'invalidstate', 'stashstate', 'untrackedfiles', and 'upstream'. The variable +# The color for each component of the prompt can specified using +# __fish_git_prompt_color_, where is one of the following and the +# values are specified as arguments to `set_color`. The variable # __fish_git_prompt_color is used for any component that does not have an -# individual color set. Colors are specified as arguments to `set_color`. +# individual color set. # -# The characters used for the optional features can be configured using -# __fish_git_prompt_char_, where is one of 'dirtystate', -# 'stagedstate', 'invalidstate', 'stashstate', 'untrackedfiles', -# 'upstream_equal', 'upstream_behind', 'upstream_ahead', and -# 'upstream_diverged'. +# prefix Anything before %s in the format string +# suffix Anything after %s in the format string +# bare Marker for a bare repository +# merging Current operation (|MERGING, |REBASE, etc.) +# branch Branch name +# upstream Upstream name and flags (with showupstream) +# +# The following optional flags have both colors, as above, and custom +# characters via __fish_git_prompt_char_. The default character is +# shown in parenthesis. +# +# __fish_git_prompt_showdirtystate +# dirtystate unstaged changes (*) +# stagedstate staged changes (+) +# invalidstate HEAD invalid (#, colored as stagedstate) +# +# __fish_git_prompt_showstashstate +# stashstate stashed changes ($) +# +# __fish_git_prompt_showuntrackedfiles +# untrackedfiles untracked files (%) +# +# __fish_git_prompt_showupstream (all colored as upstream) +# upstream_equal Branch matches upstream (=) +# upstream_behind Upstream has more commits (<) +# upstream_ahead Branch has more commits (>) +# upstream_diverged Upstream and branch have new commits (<>) set -g ___fish_git_prompt_status_order stagedstate invalidstate dirtystate untrackedfiles From 5b39d1819fdc1001ba2d1845032d6d5e32d06d5d Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Tue, 2 Jul 2013 13:10:19 -0400 Subject: [PATCH 007/170] git_prompt: Add defaults to set_color This is mostly useful for the next commit that will have different colors default to different values, but it has one immediate change: all __fish_git_prompt_color_* variables now default to __fish_git_prompt_color instead of to nothing, as they used to. --- share/functions/__fish_git_prompt.fish | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index ee6b1103e..7f312a369 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -518,6 +518,19 @@ function __fish_git_prompt_set_color set -l user_variable $$user_variable_name set -l user_variable_bright + set -l default default_done + switch (count $argv) + case 1 # No defaults given, use prompt color + set default $___fish_git_prompt_color + set default_done $___fish_git_prompt_color_done + case 2 # One default given, use normal for done + set default "$argv[2]" + set default_done (set_color normal) + case 3 # Both defaults given + set default "$argv[2]" + set default_done "$argv[3]" + end + if test (count $user_variable) -eq 2 set user_variable_bright $user_variable[2] set user_variable $user_variable[1] @@ -529,14 +542,14 @@ function __fish_git_prompt_set_color if not set -q $variable if test -n "$user_variable" if test -n "$user_variable_bright" - set -g $variable (set_color -o $user_variable) + set -g $variable (set_color --bold $user_variable) else set -g $variable (set_color $user_variable) end set -g $variable_done (set_color normal) else - set -g $variable '' - set -g $variable_done '' + set -g $variable $default + set -g $variable_done $default_done end end @@ -544,7 +557,9 @@ end function __fish_git_prompt_validate_colors --description "__fish_git_prompt helper, checks color variables" - __fish_git_prompt_set_color __fish_git_prompt_color + # Base color defaults to nothing (must be done first) + __fish_git_prompt_set_color __fish_git_prompt_color '' '' + __fish_git_prompt_set_color __fish_git_prompt_color_prefix __fish_git_prompt_set_color __fish_git_prompt_color_suffix __fish_git_prompt_set_color __fish_git_prompt_color_bare From db969dc85a190d2254edc7c00e0bf91d7d3a784a Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Fri, 26 Jul 2013 22:00:38 -0400 Subject: [PATCH 008/170] git_prompt: __fish_git_prompt_showcolorhints Based on GIT_PS1_SHOW_COLORHINTS, it introduces more color by default and also changes the color of the branch name based on if it is a real branch or detached. Based on the following commits from git.git: 9b7e776: show color hints based on state of the git tree 9b3aaf8: Fix up colored git-prompt 76c36c0: coloured git-prompt: paint detached HEAD marker in red --- share/functions/__fish_git_prompt.fish | 68 +++++++++++++++++++++----- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 7f312a369..22cfa15c1 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -67,6 +67,10 @@ # describe relative to older annotated tag (v1.6.3.1-13-gdd42c2f) # default exactly matching tag # +# If you would like a colored hint about the current dirty state, set +# __fish_git_prompt_showcolorhints to a nonempty value. The default colors are +# based on the colored output of "git status -sb" +# # This fish-compatible version of __fish_git_prompt includes some additional # features on top of the above-documented bash-compatible features: # @@ -81,11 +85,13 @@ # bare Marker for a bare repository # merging Current operation (|MERGING, |REBASE, etc.) # branch Branch name +# flags Optional flags (see below) # upstream Upstream name and flags (with showupstream) # # The following optional flags have both colors, as above, and custom # characters via __fish_git_prompt_char_. The default character is -# shown in parenthesis. +# shown in parenthesis. The default color for these flags can be also be set +# via the __fish_git_prompt_color_flags variable. # # __fish_git_prompt_showdirtystate # dirtystate unstaged changes (*) @@ -103,6 +109,16 @@ # upstream_behind Upstream has more commits (<) # upstream_ahead Branch has more commits (>) # upstream_diverged Upstream and branch have new commits (<>) +# +# Turning on __fish_git_prompt_showcolorhints changes the colors as follows to +# more closely match the behavior in bash. Note that setting any of these +# colors manually will override these defaults. +# +# branch Defaults to green +# branch_detached New color, when head is detached, default red +# dirtystate Defaults to red +# stagedstate Defaults to green +# flags Defaults to --bold blue set -g ___fish_git_prompt_status_order stagedstate invalidstate dirtystate untrackedfiles @@ -264,11 +280,12 @@ function __fish_git_prompt --description "Prompt function for Git" set -l rbc (__fish_git_prompt_operation_branch_bare $git_dir) set -l r $rbc[1] # current operation set -l b $rbc[2] # current branch + set -l detached $rbc[3] set -l w #dirty working directory set -l i #staged changes set -l s #stashes set -l u #untracked - set -l c $rbc[3] # bare repository + set -l c $rbc[4] # bare repository set -l p #upstream set -l informative_status @@ -305,6 +322,15 @@ function __fish_git_prompt --description "Prompt function for Git" __fish_git_prompt_validate_colors + set -l branch_color $___fish_git_prompt_color_branch + set -l branch_done $___fish_git_prompt_color_branch_done + if test -n "$__fish_git_prompt_showcolorhints" + if test $detached = yes + set branch_color $___fish_git_prompt_color_branch_detached + set branch_done $___fish_git_prompt_color_branch_detached_done + end + end + if test -n "$w" set w "$___fish_git_prompt_color_dirtystate$w$___fish_git_prompt_color_dirtystate_done" end @@ -319,7 +345,7 @@ function __fish_git_prompt --description "Prompt function for Git" end set b (/bin/sh -c 'echo "${1#refs/heads/}"' -- $b) if test -n "$b" - set b "$___fish_git_prompt_color_branch$b$___fish_git_prompt_color_branch_done" + set b "$branch_color$b$branch_done" end if test -n "$c" set c "$___fish_git_prompt_color_bare$c$___fish_git_prompt_color_bare_done" @@ -414,6 +440,7 @@ function __fish_git_prompt_operation_branch_bare --description "__fish_git_promp set -l git_dir $argv[1] set -l branch set -l operation + set -l detached no set -l bare set -l os @@ -476,6 +503,7 @@ function __fish_git_prompt_operation_branch_bare --description "__fish_git_promp echo $operation echo $branch + echo $detached echo $bare end @@ -555,24 +583,41 @@ function __fish_git_prompt_set_color end + function __fish_git_prompt_validate_colors --description "__fish_git_prompt helper, checks color variables" # Base color defaults to nothing (must be done first) __fish_git_prompt_set_color __fish_git_prompt_color '' '' + # Normal colors __fish_git_prompt_set_color __fish_git_prompt_color_prefix __fish_git_prompt_set_color __fish_git_prompt_color_suffix __fish_git_prompt_set_color __fish_git_prompt_color_bare __fish_git_prompt_set_color __fish_git_prompt_color_merging - __fish_git_prompt_set_color __fish_git_prompt_color_branch __fish_git_prompt_set_color __fish_git_prompt_color_cleanstate - __fish_git_prompt_set_color __fish_git_prompt_color_dirtystate - __fish_git_prompt_set_color __fish_git_prompt_color_stagedstate __fish_git_prompt_set_color __fish_git_prompt_color_invalidstate - __fish_git_prompt_set_color __fish_git_prompt_color_stashstate - __fish_git_prompt_set_color __fish_git_prompt_color_untrackedfiles __fish_git_prompt_set_color __fish_git_prompt_color_upstream + # Colors with defaults with showcolorhints + if test -n "$__fish_git_prompt_showcolorhints" + __fish_git_prompt_set_color __fish_git_prompt_color_flags (set_color --bold blue) + __fish_git_prompt_set_color __fish_git_prompt_color_branch (set_color green) + __fish_git_prompt_set_color __fish_git_prompt_color_dirtystate (set_color red) + __fish_git_prompt_set_color __fish_git_prompt_color_stagedstate (set_color green) + else + __fish_git_prompt_set_color __fish_git_prompt_color_flags + __fish_git_prompt_set_color __fish_git_prompt_color_branch + __fish_git_prompt_set_color __fish_git_prompt_color_dirtystate $___fish_git_prompt_color_flags $___fish_git_prompt_color_flags_done + __fish_git_prompt_set_color __fish_git_prompt_color_stagedstate $___fish_git_prompt_color_flags $___fish_git_prompt_color_flags_done + end + + # Branch_detached has a default, but is only used with showcolorhints + __fish_git_prompt_set_color __fish_git_prompt_color_branch_detached (set_color red) + + # Colors that depend on flags color + __fish_git_prompt_set_color __fish_git_prompt_color_stashstate $___fish_git_prompt_color_flags $___fish_git_prompt_color_flags_done + __fish_git_prompt_set_color __fish_git_prompt_color_untrackedfiles $___fish_git_prompt_color_flags $___fish_git_prompt_color_flags_done + end set -l varargs @@ -586,17 +631,18 @@ function __fish_git_prompt_repaint $varargs --description "Event handler, repain end set -l varargs -for var in '' _prefix _suffix _bare _merging _branch _dirtystate _stagedstate _invalidstate _stashstate _untrackedfiles _upstream +for var in '' _prefix _suffix _bare _merging _branch _dirtystate _stagedstate _invalidstate _stashstate _untrackedfiles _upstream _flags set varargs $varargs --on-variable __fish_git_prompt_color$var end +set varargs $varargs --on-variable __fish_git_prompt_showcolorhints function __fish_git_prompt_repaint_color $varargs --description "Event handler, repaints prompt when any color changes" if status --is-interactive set -l var $argv[3] set -e _$var set -e _{$var}_done - if test $var = __fish_git_prompt_color + if test $var = __fish_git_prompt_color -o $var = __fish_git_prompt_color_flags -o $var = __fish_git_prompt_showcolorhints # reset all the other colors too - for name in prefix suffix bare merging branch dirtystate stagedstate invalidstate stashstate untrackedfiles upstream + for name in prefix suffix bare merging branch dirtystate stagedstate invalidstate stashstate untrackedfiles upstream flags set -e ___fish_git_prompt_color_$name set -e ___fish_git_prompt_color_{$name}_done end From 914f83cb100c332f701ccacc5804c8b069fa2d41 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Wed, 3 Jul 2013 00:41:20 -0400 Subject: [PATCH 009/170] git_prompt: add bash.showUntrackedFiles option The option was added in git.git 66cb5d4, so pay attention to it like we do the other bash.* options. --- share/functions/__fish_git_prompt.fish | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 22cfa15c1..caf58beca 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -38,7 +38,10 @@ # # If you would like to see if there are untracked files, then you can set # __fish_git_prompt_showuntrackedfiles to a nonempty value. If there are -# untracked files, then a '%' will be shown next to the branch name. +# untracked files, then a '%' will be shown next to the branch name. Once you +# have set __fish_git_prompt_showuntrackedfiles, you can override it on a +# per-repository basis by setting the bash.showUntrackedFiles config variable. +# As before, this variable remains named 'bash' to preserve compatibility. # # If you would like to see the difference between HEAD and its upstream, set # __fish_git_prompt_showupstream to 'auto'. A "<" indicates you are behind, ">" @@ -308,9 +311,11 @@ function __fish_git_prompt --description "Prompt function for Git" end if test -n "$__fish_git_prompt_showuntrackedfiles" - set -l files (git ls-files --others --exclude-standard) - if test -n "$files" - set u $___fish_git_prompt_char_untrackedfiles + if test (git config --bool bash.showUntrackedFiles) != false + set -l files (git ls-files --others --exclude-standard) + if test -n "$files" + set u $___fish_git_prompt_char_untrackedfiles + end end end end From 5a7b85adc71502a22003a9d9dc754464425226dc Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Wed, 3 Jul 2013 00:43:27 -0400 Subject: [PATCH 010/170] git_prompt: use REVERT_HEAD git revert was taught to revert multiple commits, and it stores it branch information in REVERT_HEAD just like the other *_HEAD files. based on git.git 3ee4452: bash: teach __git_ps1 about REVERT_HEAD --- share/functions/__fish_git_prompt.fish | 2 ++ 1 file changed, 2 insertions(+) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index caf58beca..333267a37 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -468,6 +468,8 @@ function __fish_git_prompt_operation_branch_bare --description "__fish_git_promp set operation "|MERGING" else if test -f $git_dir/CHERRY_PICK_HEAD set operation "|CHERRY-PICKING" + else if test -f $git_dir/REVERT_HEAD + set operation "|REVERTING" else if test -f $git_dir/BISECT_LOG set operation "|BISECTING" end From 2a46b984cd990f046bb5ff3039f8e92952fab968 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Wed, 3 Jul 2013 00:50:37 -0400 Subject: [PATCH 011/170] git_prompt: show where rebase is at when stopped Adds a progress indicator to the rebase messages. (e.g. |REBASE 2/5) based on the git-prompt portion of git.git b71dc3e: "bash-prompt.sh: show where rebase is at when stopped" --- share/functions/__fish_git_prompt.fish | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 333267a37..c58ed37a7 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -447,16 +447,23 @@ function __fish_git_prompt_operation_branch_bare --description "__fish_git_promp set -l operation set -l detached no set -l bare + set -l step + set -l total set -l os - if test -f $git_dir/rebase-merge/interactive - set operation "|REBASE-i" - set branch (cat $git_dir/rebase-merge/head-name ^/dev/null) - else if test -d $git_dir/rebase-merge - set operation "|REBASE-m" + if test -d $git_dir/rebase-merge set branch (cat $git_dir/rebase-merge/head-name ^/dev/null) + set step (cat $git_dir/rebase-merge/msgnum ^/dev/null) + set total (cat $git_dir/rebase-merge/end ^/dev/null) + if test -f $git_dir/rebase-merge/interactive + set operation "|REBASE-i" + else + set operation "|REBASE-m" + end else if test -d $git_dir/rebase-apply + set step (cat $git_dir/rebase-apply/next ^/dev/null) + set total (cat $git_dir/rebase-apply/last ^/dev/null) if test -f $git_dir/rebase-apply/rebasing set operation "|REBASE" else if test -f $git_dir/rebase-apply/applying @@ -475,6 +482,10 @@ function __fish_git_prompt_operation_branch_bare --description "__fish_git_promp end end + if test -n "$step" -a -n "$total" + set operation "$operation $step/$total" + end + if test -z "$branch" set branch (git symbolic-ref HEAD ^/dev/null; set os $status) if test $os -ne 0 From ec1d2e86c81c80c03a45136827a50791de363726 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Wed, 3 Jul 2013 01:02:42 -0400 Subject: [PATCH 012/170] git_prompt: Add __fish_git_prompt_char_stateseparator Unlike the rest of the __fish_git_prompt_char_* variables, it does not have its own color because the most likely values are a space and nothing. based on git.git 15a54fb: prompt: introduce GIT_PS1_STATESEPARATOR --- share/functions/__fish_git_prompt.fish | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index c58ed37a7..17c813b55 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -113,6 +113,10 @@ # upstream_ahead Branch has more commits (>) # upstream_diverged Upstream and branch have new commits (<>) # +# The separator between the branch name and flags can also be customized via +# __fish_git_prompt_char_stateseparator. It defaults to a space ( ) and can +# only be colored by __fish_git_prompt_color. +# # Turning on __fish_git_prompt_showcolorhints changes the colors as follows to # more closely match the behavior in bash. Note that setting any of these # colors manually will override these defaults. @@ -363,9 +367,10 @@ function __fish_git_prompt --description "Prompt function for Git" end # Formatting + set -l space "$___fish_git_prompt_color$___fish_git_prompt_char_stateseparator$___fish_git_prompt_color_done" set -l f "$w$i$s$u" if test -n "$f" - set f " $f" + set f "$space$f" end set -l format $argv[1] if test -z "$format" @@ -540,7 +545,6 @@ function __fish_git_prompt_set_char if not set -q $variable set -g $variable (set -q $user_variable_name; and echo $user_variable; or echo $char) end - end function __fish_git_prompt_validate_chars --description "__fish_git_prompt helper, checks char variables" @@ -550,6 +554,7 @@ function __fish_git_prompt_validate_chars --description "__fish_git_prompt helpe __fish_git_prompt_set_char __fish_git_prompt_char_stagedstate '+' __fish_git_prompt_set_char __fish_git_prompt_char_invalidstate '#' __fish_git_prompt_set_char __fish_git_prompt_char_stashstate '$' + __fish_git_prompt_set_char __fish_git_prompt_char_stateseparator ' ' __fish_git_prompt_set_char __fish_git_prompt_char_untrackedfiles '%' __fish_git_prompt_set_char __fish_git_prompt_char_upstream_equal '=' __fish_git_prompt_set_char __fish_git_prompt_char_upstream_behind '<' @@ -669,7 +674,7 @@ function __fish_git_prompt_repaint_color $varargs --description "Event handler, end end set -l varargs -for var in dirtystate stagedstate invalidstate stashstate untrackedfiles upstream_equal upstream_behind upstream_ahead upstream_diverged +for var in dirtystate stagedstate invalidstate stashstate untrackedfiles upstream_equal upstream_behind upstream_ahead upstream_diverged stateseparator set varargs $varargs --on-variable __fish_git_prompt_char_$var end function __fish_git_prompt_repaint_char $varargs --description "Event handler, repaints prompt when any char changes" From 8642a1e68ea4e5f417d5d7d243299050cbf40681 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Wed, 3 Jul 2013 01:06:52 -0400 Subject: [PATCH 013/170] git_prompt: Display head for simple rebase based on git.git 1306321: "prompt: fix for simple rebase" --- share/functions/__fish_git_prompt.fish | 1 + 1 file changed, 1 insertion(+) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 17c813b55..963b29ecb 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -470,6 +470,7 @@ function __fish_git_prompt_operation_branch_bare --description "__fish_git_promp set step (cat $git_dir/rebase-apply/next ^/dev/null) set total (cat $git_dir/rebase-apply/last ^/dev/null) if test -f $git_dir/rebase-apply/rebasing + set branch (cat $git_dir/rebase-apply/head-name ^/dev/null) set operation "|REBASE" else if test -f $git_dir/rebase-apply/applying set operation "|AM" From 0005702399ac37bc97682c16ce136b063a27cc56 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Wed, 3 Jul 2013 01:10:59 -0400 Subject: [PATCH 014/170] git_prompt: print unique detached HEAD abbreviated object name Simply using cut duplicates (poorly) `git rev-parse --short` This also restores the ... printed after the abbreviation which __fish_git_prompt had been missing. Based on git.git e8f21ca: "bash prompt: print unique detached HEAD abbreviated object name" --- share/functions/__fish_git_prompt.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 963b29ecb..f9101b977 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -507,7 +507,7 @@ function __fish_git_prompt_operation_branch_bare --description "__fish_git_promp git describe --tags --exact-match HEAD end ^/dev/null; set os $status) if test $os -ne 0 - set branch (cut -c1-7 $git_dir/HEAD ^/dev/null; set os $status) + set branch (git rev-parse --short HEAD ^/dev/null; set os $status)... if test $os -ne 0 set branch unknown end From 87a0363ba7d2011842cec12e3144548219b2e7e1 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Wed, 3 Jul 2013 01:15:25 -0400 Subject: [PATCH 015/170] git_prompt: remove __fish_git_prompt_git_dir It's a one line function called in a single place. I suspect it only existed because the bash equivalent __gitdir existed (it was more complex), but that function no longer exists either, as of git.git 511ad15: "bash prompt: run 'git rev-parse --git-dir' directly instead of __gitdir()" --- share/functions/__fish_git_prompt.fish | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index f9101b977..948135cf1 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -281,7 +281,8 @@ function __fish_git_prompt_show_upstream --description "Helper function for __fi end function __fish_git_prompt --description "Prompt function for Git" - set -l git_dir (__fish_git_prompt_git_dir) + set -l git_dir (git rev-parse --git-dir ^/dev/null) + test -n "$git_dir"; or return set -l rbc (__fish_git_prompt_operation_branch_bare $git_dir) @@ -531,10 +532,6 @@ function __fish_git_prompt_operation_branch_bare --description "__fish_git_promp echo $bare end -function __fish_git_prompt_git_dir --description "__fish_git_prompt helper, returns .git dir if any" - echo (git rev-parse --git-dir ^/dev/null) -end - function __fish_git_prompt_set_char set -l user_variable_name "$argv[1]" set -l char $argv[2] From d534b0ba81f81ef23868878fdfa822f1bcee91b2 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Wed, 3 Jul 2013 01:29:16 -0400 Subject: [PATCH 016/170] git_prompt: Call `git rev-parse` less often The code invoked `git rev-parse` several times when the required information could be collected all at once. This is based on the following commits from git.git: efaa0c1: bash prompt: combine 'git rev-parse' executions in the main code path e3e0b93: bash prompt: combine 'git rev-parse' for detached head 0f37c12: bash prompt: use bash builtins to check for unborn branch for dirty state dd0b72c: bash prompt: use bash builtins to check stash state --- share/functions/__fish_git_prompt.fish | 45 ++++++++++++++++++-------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 948135cf1..2a44765c2 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -281,11 +281,19 @@ function __fish_git_prompt_show_upstream --description "Helper function for __fi end function __fish_git_prompt --description "Prompt function for Git" - set -l git_dir (git rev-parse --git-dir ^/dev/null) + set -l repo_info (git rev-parse --git-dir --is-inside-git-dir --is-bare-repository --is-inside-work-tree --short HEAD ^/dev/null) + test -n "$repo_info"; or return - test -n "$git_dir"; or return + set -l git_dir $repo_info[1] + set -l inside_gitdir $repo_info[2] + set -l bare_repo $repo_info[3] + set -l inside_worktree $repo_info[4] + set -l short_sha + if test (count $repo_info) = 5 + set short_sha $repo_info[5] + end - set -l rbc (__fish_git_prompt_operation_branch_bare $git_dir) + set -l rbc (__fish_git_prompt_operation_branch_bare $repo_info) set -l r $rbc[1] # current operation set -l b $rbc[2] # current branch set -l detached $rbc[3] @@ -299,7 +307,7 @@ function __fish_git_prompt --description "Prompt function for Git" __fish_git_prompt_validate_chars - if test "true" = (git rev-parse --is-inside-work-tree ^/dev/null) + if test "true" = $inside_worktree if test -n "$__fish_git_prompt_show_informative_status" set informative_status "|"(__fish_git_prompt_informative_status) else @@ -307,12 +315,12 @@ function __fish_git_prompt --description "Prompt function for Git" set -l config (git config --bool bash.showDirtyState) if test "$config" != "false" set w (__fish_git_prompt_dirty) - set i (__fish_git_prompt_staged) + set i (__fish_git_prompt_staged $short_sha) end end - if test -n "$__fish_git_prompt_showstashstate" - git rev-parse --verify refs/stash >/dev/null ^&1; and set s $___fish_git_prompt_char_stashstate + if test -n "$__fish_git_prompt_showstashstate" -a -r $git_dir/refs/stash + set s $___fish_git_prompt_char_stashstate end if test -n "$__fish_git_prompt_showuntrackedfiles" @@ -384,9 +392,11 @@ end ### helper functions function __fish_git_prompt_staged --description "__fish_git_prompt helper, tells whether or not the current branch has staged files" + set -l short_sha $argv[1] + set -l staged - if git rev-parse --quiet --verify HEAD >/dev/null + if test -n "$short_sha" git diff-index --cached --quiet HEAD --; or set staged $___fish_git_prompt_char_stagedstate else set staged $___fish_git_prompt_char_invalidstate @@ -448,7 +458,15 @@ end # Keeping these together avoids many duplicated checks function __fish_git_prompt_operation_branch_bare --description "__fish_git_prompt helper, returns the current Git operation and branch" - set -l git_dir $argv[1] + # This function is passed the full repo_info array + set -l git_dir $argv[1] + set -l inside_gitdir $argv[2] + set -l bare_repo $argv[3] + set -l short_sha + if test (count $argv) = 5 + set short_sha $argv[5] + end + set -l branch set -l operation set -l detached no @@ -508,8 +526,9 @@ function __fish_git_prompt_operation_branch_bare --description "__fish_git_promp git describe --tags --exact-match HEAD end ^/dev/null; set os $status) if test $os -ne 0 - set branch (git rev-parse --short HEAD ^/dev/null; set os $status)... - if test $os -ne 0 + if test -n "$short_sha" + set branch $short_sha... + else set branch unknown end end @@ -517,8 +536,8 @@ function __fish_git_prompt_operation_branch_bare --description "__fish_git_promp end end - if test "true" = (git rev-parse --is-inside-git-dir ^/dev/null) - if test "true" = (git rev-parse --is-bare-repository ^/dev/null) + if test "true" = $inside_gitdir + if test "true" = $bare_repo set bare "BARE:" else # Let user know they're inside the git dir of a non-bare repo From 6faeb71770ff158984a7edffa8c8de62b065cccc Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Wed, 3 Jul 2013 01:40:08 -0400 Subject: [PATCH 017/170] git_prompt: don't save output of ls-files for untracked files based on git.git 14d7649: "bash prompt: avoid command substitution when checking for untracked files" --- share/functions/__fish_git_prompt.fish | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 2a44765c2..f0bc022a8 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -325,8 +325,7 @@ function __fish_git_prompt --description "Prompt function for Git" if test -n "$__fish_git_prompt_showuntrackedfiles" if test (git config --bool bash.showUntrackedFiles) != false - set -l files (git ls-files --others --exclude-standard) - if test -n "$files" + if git ls-files --others --exclude-standard --error-unmatch -- '*' >/dev/null ^/dev/null set u $___fish_git_prompt_char_untrackedfiles end end From c82dbaca8b3c2696f8365d8df63de09838c81ef8 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Fri, 26 Jul 2013 17:20:05 -0400 Subject: [PATCH 018/170] git-prompt: Ensure repaint on all char and color changes A few characters and colors got added without being added to the event list for repainting. Also sort and re-align list of characters in validate_chars. --- share/functions/__fish_git_prompt.fish | 29 +++++++++++++------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index f0bc022a8..97c4a6660 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -565,18 +565,18 @@ end function __fish_git_prompt_validate_chars --description "__fish_git_prompt helper, checks char variables" - __fish_git_prompt_set_char __fish_git_prompt_char_cleanstate '.' - __fish_git_prompt_set_char __fish_git_prompt_char_dirtystate '*' - __fish_git_prompt_set_char __fish_git_prompt_char_stagedstate '+' - __fish_git_prompt_set_char __fish_git_prompt_char_invalidstate '#' - __fish_git_prompt_set_char __fish_git_prompt_char_stashstate '$' - __fish_git_prompt_set_char __fish_git_prompt_char_stateseparator ' ' - __fish_git_prompt_set_char __fish_git_prompt_char_untrackedfiles '%' - __fish_git_prompt_set_char __fish_git_prompt_char_upstream_equal '=' - __fish_git_prompt_set_char __fish_git_prompt_char_upstream_behind '<' - __fish_git_prompt_set_char __fish_git_prompt_char_upstream_ahead '>' - __fish_git_prompt_set_char __fish_git_prompt_char_upstream_diverged '<>' - __fish_git_prompt_set_char __fish_git_prompt_char_upstream_prefix ' ' + __fish_git_prompt_set_char __fish_git_prompt_char_cleanstate '.' + __fish_git_prompt_set_char __fish_git_prompt_char_dirtystate '*' + __fish_git_prompt_set_char __fish_git_prompt_char_invalidstate '#' + __fish_git_prompt_set_char __fish_git_prompt_char_stagedstate '+' + __fish_git_prompt_set_char __fish_git_prompt_char_stashstate '$' + __fish_git_prompt_set_char __fish_git_prompt_char_stateseparator ' ' + __fish_git_prompt_set_char __fish_git_prompt_char_untrackedfiles '%' + __fish_git_prompt_set_char __fish_git_prompt_char_upstream_ahead '>' + __fish_git_prompt_set_char __fish_git_prompt_char_upstream_behind '<' + __fish_git_prompt_set_char __fish_git_prompt_char_upstream_diverged '<>' + __fish_git_prompt_set_char __fish_git_prompt_char_upstream_equal '=' + __fish_git_prompt_set_char __fish_git_prompt_char_upstream_prefix ' ' end @@ -670,7 +670,7 @@ function __fish_git_prompt_repaint $varargs --description "Event handler, repain end set -l varargs -for var in '' _prefix _suffix _bare _merging _branch _dirtystate _stagedstate _invalidstate _stashstate _untrackedfiles _upstream _flags +for var in '' _prefix _suffix _bare _merging _cleanstate _invalidstate _upstream _flags _branch _dirtystate _stagedstate _branch_detached _stashstate _untrackedfiles set varargs $varargs --on-variable __fish_git_prompt_color$var end set varargs $varargs --on-variable __fish_git_prompt_showcolorhints @@ -689,8 +689,9 @@ function __fish_git_prompt_repaint_color $varargs --description "Event handler, commandline -f repaint ^/dev/null end end + set -l varargs -for var in dirtystate stagedstate invalidstate stashstate untrackedfiles upstream_equal upstream_behind upstream_ahead upstream_diverged stateseparator +for var in cleanstate dirtystate invalidstate stagedstate stashstate stateseparator untrackedfiles upstream_ahead upstream_behind upstream_diverged upstream_equal upstream_prefix set varargs $varargs --on-variable __fish_git_prompt_char_$var end function __fish_git_prompt_repaint_char $varargs --description "Event handler, repaints prompt when any char changes" From 92d2e681d6c88752c0e2c16945a656dd78f73d6e Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Fri, 26 Jul 2013 20:58:41 -0400 Subject: [PATCH 019/170] git-prompt: Move status_order to near informative_status It's easy to forget the definition of ___fish_git_prompt_status_order when there are dozens of lines between where it is defined and where it is used. --- share/functions/__fish_git_prompt.fish | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 97c4a6660..b2274256c 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -127,8 +127,6 @@ # stagedstate Defaults to green # flags Defaults to --bold blue -set -g ___fish_git_prompt_status_order stagedstate invalidstate dirtystate untrackedfiles - function __fish_git_prompt_show_upstream --description "Helper function for __fish_git_prompt" set -l show_upstream $__fish_git_prompt_showupstream set -l svn_prefix # For better SVN upstream information @@ -415,6 +413,8 @@ function __fish_git_prompt_dirty --description "__fish_git_prompt helper, tells echo $dirty end +set -g ___fish_git_prompt_status_order stagedstate invalidstate dirtystate untrackedfiles + function __fish_git_prompt_informative_status set -l changedFiles (git diff --name-status | cut -c 1-2) From 8dd9602f0615ec2311b03391f3ed5d88f9029cc6 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Fri, 26 Jul 2013 21:00:45 -0400 Subject: [PATCH 020/170] git-prompt: Document informative_status changes --- share/functions/__fish_git_prompt.fish | 34 ++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index b2274256c..51f0e2303 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -17,10 +17,11 @@ # # The behavior of __fish_git_prompt is very heavily based off of the bash # script's __git_ps1 function. As such, usage and customization is very -# similar, although some extra flexibility is provided in this script. +# similar, although some extra features are provided in this script. # Due to differences between bash and fish, the PROMPT_COMMAND style where # passing two or three arguments causes the fucnction to set PS1 is not -# supported. +# supported. More information on the additional features is found after the +# bash-compatable documentation. # # The argument to __fish_git_prompt will be displayed only if you are currently # in a git repository. The %s token will be the name of the branch. @@ -49,7 +50,8 @@ # that there is no difference. You can further control behavior by setting # __fish_git_prompt_showupstream to a space-separated list of values: # -# verbose show number of commits head/behind (+/-) upstream +# verbose show number of commits ahead/behind (+/-) upstream +# informative similar to verbose, but shows nothing when equal (fish only) # legacy don't use the '--count' option available in recent versions # of git-rev-list # git always compare HEAD to @{upstream} @@ -73,9 +75,21 @@ # If you would like a colored hint about the current dirty state, set # __fish_git_prompt_showcolorhints to a nonempty value. The default colors are # based on the colored output of "git status -sb" + + +# __fish_git_prompt includes some additional features on top of the +# above-documented bash-compatible features: # -# This fish-compatible version of __fish_git_prompt includes some additional -# features on top of the above-documented bash-compatible features: +# +# An "informative git prompt" mode similar to the scripts for bash and zsh +# can be activated by setting __fish_git_prompt_show_informative_status +# This works more like the "informative git prompt" scripts for bash and zsh, +# giving prompts like (master|+1#2*3%4) where master is the current branch +# and you have 1 staged, 2 unmerged, 3 dirty, and 4 untracked files. If you +# have no changes, it displays (master|.). The characters and colors can be +# customized as below, with the following names: +# +# dirtystate, invalidstate, stagedstate, untrackedfiles, cleanstate # # The color for each component of the prompt can specified using # __fish_git_prompt_color_, where is one of the following and the @@ -91,6 +105,7 @@ # flags Optional flags (see below) # upstream Upstream name and flags (with showupstream) # +# # The following optional flags have both colors, as above, and custom # characters via __fish_git_prompt_char_. The default character is # shown in parenthesis. The default color for these flags can be also be set @@ -113,10 +128,19 @@ # upstream_ahead Branch has more commits (>) # upstream_diverged Upstream and branch have new commits (<>) # +# __fish_git_prompt_show_informative_status +# (see also the flags for showdirtystate and showuntrackedfiles, above) +# cleanstate Working directory has no changes (.) +# +# # The separator between the branch name and flags can also be customized via # __fish_git_prompt_char_stateseparator. It defaults to a space ( ) and can # only be colored by __fish_git_prompt_color. # +# The separator before the upstream information can be customized via +# __fish_git_prompt_char_upstream_prefix. It defaults to a space ( ) and is +# colored as part of the upstream information. +# # Turning on __fish_git_prompt_showcolorhints changes the colors as follows to # more closely match the behavior in bash. Note that setting any of these # colors manually will override these defaults. From e3ea953ff406fdab58c7ced150f29e7b27614da3 Mon Sep 17 00:00:00 2001 From: waterhouse Date: Fri, 26 Jul 2013 20:35:34 -0700 Subject: [PATCH 021/170] Ctrl+E should insert suggested completion and then go to end of line (Closes #91, #932) Currently, control-E is bound to `end-of-line`. This patch modifes the `end-of-line` procedure so that, if it is invoked when the cursor is at the end of a command and there is pending completion text, it will accept the completion text and move to the end. The behavior of `end-of-line` will not otherwise be altered. --- reader.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/reader.cpp b/reader.cpp index 8febb7994..7753bd759 100644 --- a/reader.cpp +++ b/reader.cpp @@ -3114,10 +3114,17 @@ const wchar_t *reader_readline(void) case R_END_OF_LINE: { - while (buff[data->buff_pos] && - buff[data->buff_pos] != L'\n') + if (data->buff_pos < data->command_length()) { - data->buff_pos++; + while (buff[data->buff_pos] && + buff[data->buff_pos] != L'\n') + { + data->buff_pos++; + } + } + else + { + accept_autosuggestion(true); } reader_repaint(); From 6aebeca1d0ff0e7a4a394247637e4475d16c672c Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sat, 27 Jul 2013 12:45:48 +0200 Subject: [PATCH 022/170] Highlight incorrect use of command or exec --- highlight.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/highlight.cpp b/highlight.cpp index 606604386..fd5ffb790 100644 --- a/highlight.cpp +++ b/highlight.cpp @@ -1035,7 +1035,7 @@ static void tokenize(const wchar_t * const buff, std::vector &color, const bool is_cmd = false; int is_subcommand = 0; int mark = tok_get_pos(&tok); - color.at(tok_get_pos(&tok)) = HIGHLIGHT_COMMAND; + color.at(tok_get_pos(&tok)) = use_builtin ? HIGHLIGHT_COMMAND : HIGHLIGHT_ERROR; if (parser_keywords_is_subcommand(cmd)) { @@ -1048,7 +1048,7 @@ static void tokenize(const wchar_t * const buff, std::vector &color, const use_command = 0; use_builtin = 1; } - else if (cmd == L"command") + else if (cmd == L"command" || cmd == L"exec") { use_command = 1; use_function = 0; From 70fbb4623f81631651cfa175a73f15cdcde64292 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Sat, 27 Jul 2013 09:58:45 -0400 Subject: [PATCH 023/170] git_prompt: Fix resetting colors in informative_status --- share/functions/__fish_git_prompt.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 51f0e2303..60bfa4c68 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -457,7 +457,7 @@ function __fish_git_prompt_informative_status for i in $___fish_git_prompt_status_order if [ $$i != "0" ] set -l color_var ___fish_git_prompt_color_$i - set -l color_done_var ___fish_git_prompt_color_$i + set -l color_done_var ___fish_git_prompt_color_{$i}_done set -l symbol_var ___fish_git_prompt_char_$i set -l color $$color_var From c62d9c37d2d6a97800f12857cb431c6543347bd1 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Sat, 27 Jul 2013 09:59:36 -0400 Subject: [PATCH 024/170] git_prompt: Repaint when show_informative_status is changed --- share/functions/__fish_git_prompt.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 60bfa4c68..7d46e82a8 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -684,7 +684,7 @@ function __fish_git_prompt_validate_colors --description "__fish_git_prompt help end set -l varargs -for var in repaint describe_style showdirtystate showstashstate showuntrackedfiles showupstream +for var in repaint describe_style show_informative_status showdirtystate showstashstate showuntrackedfiles showupstream set varargs $varargs --on-variable __fish_git_prompt_$var end function __fish_git_prompt_repaint $varargs --description "Event handler, repaints prompt when functionality changes" From aa8b3cb6d6195761412406b532283236a34bf7d0 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Sat, 27 Jul 2013 10:35:46 -0400 Subject: [PATCH 025/170] git_prompt: fix non-informative upstream `test -n informative` will always succeed. We want to test the informative variable instead so that other modes can still work. --- share/functions/__fish_git_prompt.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 7d46e82a8..e1f9a8fdb 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -275,7 +275,7 @@ function __fish_git_prompt_show_upstream --description "Helper function for __fi case '*' # diverged from upstream echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_diverged$ahead-$behind" end - else if test -n informative + else if test -n "$informative" echo $count | read -l behind ahead switch "$count" case '' # no upstream From 0479f0ad6309139c0f318ece9c637b965e582574 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sat, 27 Jul 2013 17:08:06 +0200 Subject: [PATCH 026/170] Remove useless debugging code --- share/tools/create_manpage_completions.py | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/share/tools/create_manpage_completions.py b/share/tools/create_manpage_completions.py index 24650ac6e..8bf41e42c 100755 --- a/share/tools/create_manpage_completions.py +++ b/share/tools/create_manpage_completions.py @@ -952,18 +952,4 @@ if __name__ == "__main__": if e.errno != errno.EEXIST: raise - if True: - parse_and_output_man_pages(file_paths, output_directory, show_progress) - else: - # Profiling code - import cProfile, pstats - cProfile.run('parse_and_output_man_pages(file_paths, output_directory, show_progress)', 'fooprof') - p = pstats.Stats('fooprof') - p.sort_stats('cumulative').print_stats(100) - - # Here we can write out all the parser infos - if False: - for name in PARSER_INFO: - print('Parser ' + name + ':') - print('\t' + ', '.join(PARSER_INFO[name])) - print('') + parse_and_output_man_pages(file_paths, output_directory, show_progress) From be77b9201e003cd11bd638f01882a4be0b9905e9 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sun, 28 Jul 2013 20:49:12 +0200 Subject: [PATCH 027/170] Rename STYLEGUIDE.md to CONTRIBUTING.md, so GitHub would notice it. --- STYLEGUIDE.md => CONTRIBUTING.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename STYLEGUIDE.md => CONTRIBUTING.md (100%) diff --git a/STYLEGUIDE.md b/CONTRIBUTING.md similarity index 100% rename from STYLEGUIDE.md rename to CONTRIBUTING.md From 27d84ef8bec7eaf9d6eda54ab29f1572fc9197af Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Mon, 29 Jul 2013 16:06:05 +0800 Subject: [PATCH 028/170] documentation for test and function (closes: #734) plus speling in documentation for bind. Note that this commit does not re-enable the generation of the manpage for test, which will therefore still fall through to the system manual page with `man test`. --- doc_src/bind.txt | 2 +- doc_src/function.txt | 5 ++- doc_src/test.txt | 98 ++++++++++++++++++++++++++++++++++---------- 3 files changed, 81 insertions(+), 24 deletions(-) diff --git a/doc_src/bind.txt b/doc_src/bind.txt index 614a14950..add185a11 100644 --- a/doc_src/bind.txt +++ b/doc_src/bind.txt @@ -48,7 +48,7 @@ readable as well. Key bindings are not saved between sessions by default. To save custom keybindings, edit the \c fish_user_key_bindings function and insert the -appropirate \c bind statements. +appropriate \c bind statements. The following parameters are available: diff --git a/doc_src/function.txt b/doc_src/function.txt index c072c5518..8d8e45193 100644 --- a/doc_src/function.txt +++ b/doc_src/function.txt @@ -12,16 +12,19 @@ function is given as a command. The following options are available: +- -a NAMES or --argument-names NAMES assigns the value of successive command-line arguments to the names given in NAMES. - -d DESCRIPTION or \c --description=DESCRIPTION is a description of what the function does, suitable as a completion description. - -e or --on-event EVENT_NAME tells fish to run this function when the specified named event is emitted. Fish internally generates named events e.g. when showing the prompt. - -j PID or --on-job-exit PID tells fish to run this function when the job with group ID PID exits. Instead of PID, the string 'caller' can be specified. This is only legal when in a command substitution, and will result in the handler being triggered by the exit of the job which created this command substitution. - -p PID or --on-process-exit PID tells fish to run this function when the fish child process with process ID PID exits. - -s or --on-signal SIGSPEC tells fish to run this function when the signal SIGSPEC is delivered. SIGSPEC can be a signal number, or the signal name, such as SIGHUP (or just HUP). +- \c -S or \c --no-scope-shadowing allows the function to access the variables of calling functions. Normally, any variables inside the function that have the same name as variables from the calling function are "shadowed", and their contents is independent of the calling function. - -v or --on-variable VARIABLE_NAME tells fish to run this function when the variable VARIABLE_NAME changes value. If the user enters any additional arguments after the function, they are inserted into the environment variable array -$argv. +$argv. If the \c --argument-names option is provided, the arguments are +also assigned to names specified in that option. By using one of the event handler switches, a function can be made to run automatically at specific events. The user may generate new events using the emit builtin. Fish generates the following named events: diff --git a/doc_src/test.txt b/doc_src/test.txt index 600e7ea78..fc64118e7 100644 --- a/doc_src/test.txt +++ b/doc_src/test.txt @@ -6,37 +6,91 @@ \subsection test-description Description Tests the expression given and sets the exit status to 0 if true, -and 1 if false. +and 1 if false. An expression is made up of one or more operators +and their arguments. -The following options are available: -- \c -h displays a help message and then exits. -- -L FILE returns true if \c FILE is a symbolic link. -- -S FILE returns true if \c FILE is a socket. -- COND1 -a COND2 combines two conditions with a logical and. +The following operators are available to examine files and directories: - -b FILE returns true if \c FILE is a block device. - -c FILE returns true if \c FILE is a character device. - -d FILE returns true if \c FILE is a directory. - -e FILE returns true if \c FILE exists. - -f FILE returns true if \c FILE is a regular file. -- -f FILE returns true if \c FILE has set-group-ID bit set. -- -n STRING returns true if the length of \c STRING is non-zero. -- COND1 -o COND2 combines two conditions with a logical or. +- -g FILE returns true if \c FILE has the set-group-ID bit set. +- -L FILE returns true if \c FILE is a symbolic link. - -p FILE returns true if \c FILE is a named pipe. -- -r FILE returns true if \c FILE is readable. -- -s FILE returns true if the size of \c FILE is non-zero. -- -t FD returns true if \c FD is a terminal (TTY). -- -u FILE returns true if \c FILE has set-user-ID bit set. -- -w FILE returns true if \c FILE is writable. -- -x FILE returns true if \c FILE is executable. -- -z STRING returns true if \c STRING length is zero. +- -r FILE returns true if \c FILE is marked as readable. +- -s FILE returns true if the size of \c FILE is greater than zero. +- -S FILE returns true if \c FILE is a socket. +- -t FD returns true if the file descriptor \c FD is a terminal (TTY). +- -u FILE returns true if \c FILE has the set-user-ID bit set. +- -w FILE returns true if \c FILE is marked as writable; note that this does not check if the filesystem is read-only. +- -x FILE returns true if \c FILE is marked as executable. -\subsection test-example Example +The following operators are available to compare and examine text strings: +- STRING1 = STRING2 returns true if the strings \c STRING1 and +\c STRING2 are identical. +- STRING1 != STRING2 returns true if the strings \c STRING1 and +\c STRING2 are not identical. +- -n STRING returns true if the length of \c STRING is non-zero. +- -z STRING returns true if the length of \c STRING is zero. + +The following operators are available to compare and examine numbers: +- NUM1 -eq NUM2 returns true if \c NUM1 and \c NUM2 are numerically equal. +- NUM1 -ne NUM2 returns true if \c NUM1 and \c NUM2 are not numerically equal. +- NUM1 -gt NUM2 returns true if \c NUM1 is greater than NUM2. +- NUM1 -ge NUM2 returns true if \c NUM1 is greater than or equal to NUM2. +- NUM1 -lt NUM2 returns true if \c NUM1 is less than NUM2. +- NUM1 -le NUM2 returns true if \c NUM1 is less than or equal to NUM2. + +Note that only integers are supported. For more complex mathematical +operations, including fractions, the \c env program may be useful. Consult the +documentation for your operating system. + +Expressions can be combined using the following operators: +- COND1 -a COND2 returns true if both \c COND1 and \c COND2 are true. +- COND1 -o COND2 returns true if either \c COND1 or \c COND2 are true. + +Expressions can be inverted using the \c ! operator: +- ! EXPRESSION returns true if \c EXPRESSION is false, and false if +\c EXPRESSION is true. + +Expressions can be grouped using parentheses. +- ( EXPRESSION ) returns the value of EXPRESSION. +Note that parentheses will usually require escaping with \\( to avoid +being interpreted as a command substitution. + +\subsection test-example Examples + +If the \c /tmp directory exists, copy the \c /etc/motd file to it:
-if test -d "/"
-    echo "Fish is cool"
+if test -d /tmp
+    cp /etc/motd /tmp/motd
 end
-
+ + +If the variable \c MANPATH is defined and not empty, print the contents: + +
+if test -n $MANPATH
+    echo $MANPATH
+end
+
+ +Parentheses and the \c -o and \c -a operators can be combined to produce +more complicated expressions. In this example, success is printed if there is +a \c /foo or \c /bar file as well as a \c /baz or \c /bat file. + +
+if test \\( -f /foo -o -f /bar \\) -a \\( -f /baz -o -f /bat \\)
+    echo Success.
+end.
+
+ +\subsection test-standards Standards + +\c test implements a subset of the +IEEE Std 1003.1-2008 +(POSIX.1) standard. The following exceptions apply: +- The \c < and \c > operators for comparing strings are not implemented. -Because "/" is a directory, the expression will evaluate to true, and -"Fish is cool" will be output. From 3af40efdb1e9799a14931eacdc4a4ee7703cf951 Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Mon, 29 Jul 2013 17:59:38 +0800 Subject: [PATCH 029/170] builtin_test: drop unused condstr --- builtin_test.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/builtin_test.cpp b/builtin_test.cpp index 7f1792f11..1cf798960 100644 --- a/builtin_test.cpp +++ b/builtin_test.cpp @@ -23,12 +23,6 @@ enum int builtin_test(parser_t &parser, wchar_t **argv); -static const wchar_t * const condstr[] = -{ - L"!", L"&&", L"||", L"==", L"!=", L"<", L">", L"-nt", L"-ot", L"-ef", L"-eq", - L"-ne", L"-lt", L"-gt", L"-le", L"-ge", L"=~" -}; - namespace test_expressions { From c4bc216815db36fbfbccd1adda255c40314c8ebb Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Sat, 27 Jul 2013 10:59:50 -0400 Subject: [PATCH 030/170] git_prompt: Informative upstream with informative status This makes $__fish_git_prompt_showupstream = "auto" mean "informative" instead of "git" if $__fish_git_prompt_show_informative_status is set. --- share/functions/__fish_git_prompt.fish | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index e1f9a8fdb..485f5d1d4 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -162,6 +162,11 @@ function __fish_git_prompt_show_upstream --description "Helper function for __fi set -l legacy set -l verbose + # Default to informative if show_informative_status is set + if test -n "$__fish_git_prompt_show_informative_status" + set informative 1 + end + set -l svn_remote # get some config options from git-config git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' ^/dev/null | tr '\0\n' '\n ' | while read -l key value @@ -186,16 +191,20 @@ function __fish_git_prompt_show_upstream --description "Helper function for __fi end # parse configuration variables + # and clear informative default when needed for option in $show_upstream switch $option case git svn set upstream $option + set -e informative case verbose set verbose 1 + set -e informative case informative set informative 1 case legacy set legacy 1 + set -e informative end end From 1964b04ea9d3bcddd5cfed2b2abe5a2adb69856b Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Sat, 27 Jul 2013 11:04:54 -0400 Subject: [PATCH 031/170] git_prompt: Show upstream with informative status This makes $__fish_git_prompt_show_informative_status imply $__fish_git_prompt_showupstream = "informative", while adding a none option for showupstream to disable it if desired. --- share/functions/__fish_git_prompt.fish | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 485f5d1d4..a36dab29a 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -56,6 +56,7 @@ # of git-rev-list # git always compare HEAD to @{upstream} # svn always compare HEAD to your SVN upstream +# none disables (fish only, useful with show_informative_status) # # By default, __fish_git_prompt will compare HEAD to your SVN upstream if it # can find one, or @{upstream} otherwise. Once you have set @@ -84,12 +85,14 @@ # An "informative git prompt" mode similar to the scripts for bash and zsh # can be activated by setting __fish_git_prompt_show_informative_status # This works more like the "informative git prompt" scripts for bash and zsh, -# giving prompts like (master|+1#2*3%4) where master is the current branch -# and you have 1 staged, 2 unmerged, 3 dirty, and 4 untracked files. If you -# have no changes, it displays (master|.). The characters and colors can be -# customized as below, with the following names: +# giving prompts like (master >1<2|+3#4*5%6) where master is the current branch, +# you have 1 commit your upstream doesn't and it has 2 you don't, and you have +# 3 staged, 4 unmerged, 5 dirty, and 6 untracked files. If you have no +# changes, it displays (master|.). The characters and colors can be customized +# as below, with the following names: # -# dirtystate, invalidstate, stagedstate, untrackedfiles, cleanstate +# upstream_prefix, upstream_ahead, upstream_behind, dirtystate, +# invalidstate, stagedstate, untrackedfiles, cleanstate # # The color for each component of the prompt can specified using # __fish_git_prompt_color_, where is one of the following and the @@ -205,6 +208,8 @@ function __fish_git_prompt_show_upstream --description "Helper function for __fi case legacy set legacy 1 set -e informative + case none + return end end @@ -363,7 +368,7 @@ function __fish_git_prompt --description "Prompt function for Git" end end - if test -n "$__fish_git_prompt_showupstream" + if test -n "$__fish_git_prompt_showupstream" -o "$__fish_git_prompt_show_informative_status" set p (__fish_git_prompt_show_upstream) end end From b280cc5e750220b95ec2fc3910e326704f6c50f5 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Sat, 27 Jul 2013 11:08:33 -0400 Subject: [PATCH 032/170] git_prompt: Change informative character defaults MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes the defaults for several characters when $__fish_git_prompt_show_informative_status is set so that the prompt looks more like the typical informative prompt. Before: (master >1<2|+3#4*5%6) After: (master↑1↓2|●3✖4✚5…6) The defaults were taken from magicmonty/bash-git-prompt --- share/functions/__fish_git_prompt.fish | 56 +++++++++++++++++++------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index a36dab29a..af5cdbe6b 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -85,14 +85,25 @@ # An "informative git prompt" mode similar to the scripts for bash and zsh # can be activated by setting __fish_git_prompt_show_informative_status # This works more like the "informative git prompt" scripts for bash and zsh, -# giving prompts like (master >1<2|+3#4*5%6) where master is the current branch, +# giving prompts like (master↑1↓2|●3✖4✚5…6) where master is the current branch, # you have 1 commit your upstream doesn't and it has 2 you don't, and you have # 3 staged, 4 unmerged, 5 dirty, and 6 untracked files. If you have no -# changes, it displays (master|.). The characters and colors can be customized -# as below, with the following names: +# changes, it displays (master|✔). +# +# Setting __fish_git_prompt_show_informative_status changes several defaults. +# The default mode for __fish_git_prompt_showupstream changes to informative +# and the following characters have their defaults changed. (The characters +# and colors can still be customized as described below.) +# +# upstream_prefix () +# upstream_ahead (↑) +# upstream_behind (↓) +# dirtystate (✚) +# invalidstate (✖) +# stagedstate (●) +# untrackedfiles (…) +# cleanstate (✔) # -# upstream_prefix, upstream_ahead, upstream_behind, dirtystate, -# invalidstate, stagedstate, untrackedfiles, cleanstate # # The color for each component of the prompt can specified using # __fish_git_prompt_color_, where is one of the following and the @@ -133,7 +144,7 @@ # # __fish_git_prompt_show_informative_status # (see also the flags for showdirtystate and showuntrackedfiles, above) -# cleanstate Working directory has no changes (.) +# cleanstate Working directory has no changes (✔) # # # The separator between the branch name and flags can also be customized via @@ -141,8 +152,10 @@ # only be colored by __fish_git_prompt_color. # # The separator before the upstream information can be customized via -# __fish_git_prompt_char_upstream_prefix. It defaults to a space ( ) and is -# colored as part of the upstream information. +# __fish_git_prompt_char_upstream_prefix. It is colored like the rest of +# the upstream information. It normallly defaults to a space ( ) and defaults +# to nothing () when __fish_git_prompt_show_informative_status is set. +# # # Turning on __fish_git_prompt_showcolorhints changes the colors as follows to # more closely match the behavior in bash. Note that setting any of these @@ -593,6 +606,12 @@ function __fish_git_prompt_set_char set -l char $argv[2] set -l user_variable $$user_variable_name + if test (count $argv) -ge 3 + if test -n "$__fish_git_prompt_show_informative_status" + set char $argv[3] + end + end + set -l variable _$user_variable_name set -l variable_done "$variable"_done @@ -603,15 +622,15 @@ end function __fish_git_prompt_validate_chars --description "__fish_git_prompt helper, checks char variables" - __fish_git_prompt_set_char __fish_git_prompt_char_cleanstate '.' - __fish_git_prompt_set_char __fish_git_prompt_char_dirtystate '*' - __fish_git_prompt_set_char __fish_git_prompt_char_invalidstate '#' - __fish_git_prompt_set_char __fish_git_prompt_char_stagedstate '+' + __fish_git_prompt_set_char __fish_git_prompt_char_cleanstate '✔' + __fish_git_prompt_set_char __fish_git_prompt_char_dirtystate '*' '✚' + __fish_git_prompt_set_char __fish_git_prompt_char_invalidstate '#' '✖' + __fish_git_prompt_set_char __fish_git_prompt_char_stagedstate '+' '●' __fish_git_prompt_set_char __fish_git_prompt_char_stashstate '$' __fish_git_prompt_set_char __fish_git_prompt_char_stateseparator ' ' - __fish_git_prompt_set_char __fish_git_prompt_char_untrackedfiles '%' - __fish_git_prompt_set_char __fish_git_prompt_char_upstream_ahead '>' - __fish_git_prompt_set_char __fish_git_prompt_char_upstream_behind '<' + __fish_git_prompt_set_char __fish_git_prompt_char_untrackedfiles '%' '…' + __fish_git_prompt_set_char __fish_git_prompt_char_upstream_ahead '>' '↑' + __fish_git_prompt_set_char __fish_git_prompt_char_upstream_behind '<' '↓' __fish_git_prompt_set_char __fish_git_prompt_char_upstream_diverged '<>' __fish_git_prompt_set_char __fish_git_prompt_char_upstream_equal '=' __fish_git_prompt_set_char __fish_git_prompt_char_upstream_prefix ' ' @@ -703,6 +722,13 @@ for var in repaint describe_style show_informative_status showdirtystate showsta end function __fish_git_prompt_repaint $varargs --description "Event handler, repaints prompt when functionality changes" if status --is-interactive + if test $argv[3] = __fish_git_prompt_show_informative_status + # Clear characters that have different defaults with/without informative status + for name in cleanstate dirtystate invalidstate stagedstate stateseparator untrackedfiles upstream_ahead upstream_behind + set -e ___fish_git_prompt_char_$name + end + end + commandline -f repaint ^/dev/null end end From 82b589e3909d6587c30aa7001a26ac66240a645b Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Sat, 27 Jul 2013 11:12:34 -0400 Subject: [PATCH 033/170] git_prompt: Make informative separator configurable It reuses $__fish_git_prompt_char_stateseparator, since it has a similar meaning and goes otherwise unused when $__fish_git_prompt_show_informative_status is set. --- share/functions/__fish_git_prompt.fish | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index af5cdbe6b..610bdd6a5 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -98,6 +98,7 @@ # upstream_prefix () # upstream_ahead (↑) # upstream_behind (↓) +# stateseparator (|) # dirtystate (✚) # invalidstate (✖) # stagedstate (●) @@ -148,8 +149,9 @@ # # # The separator between the branch name and flags can also be customized via -# __fish_git_prompt_char_stateseparator. It defaults to a space ( ) and can -# only be colored by __fish_git_prompt_color. +# __fish_git_prompt_char_stateseparator. It can only be colored by +# __fish_git_prompt_color. It normally defaults to a space ( ) and defaults +# to a vertical bar (|) when __fish_git_prompt_show_informative_status is set. # # The separator before the upstream information can be customized via # __fish_git_prompt_char_upstream_prefix. It is colored like the rest of @@ -358,7 +360,7 @@ function __fish_git_prompt --description "Prompt function for Git" if test "true" = $inside_worktree if test -n "$__fish_git_prompt_show_informative_status" - set informative_status "|"(__fish_git_prompt_informative_status) + set informative_status "$___fish_git_prompt_char_stateseparator"(__fish_git_prompt_informative_status) else if test -n "$__fish_git_prompt_showdirtystate" set -l config (git config --bool bash.showDirtyState) @@ -627,7 +629,7 @@ function __fish_git_prompt_validate_chars --description "__fish_git_prompt helpe __fish_git_prompt_set_char __fish_git_prompt_char_invalidstate '#' '✖' __fish_git_prompt_set_char __fish_git_prompt_char_stagedstate '+' '●' __fish_git_prompt_set_char __fish_git_prompt_char_stashstate '$' - __fish_git_prompt_set_char __fish_git_prompt_char_stateseparator ' ' + __fish_git_prompt_set_char __fish_git_prompt_char_stateseparator ' ' '|' __fish_git_prompt_set_char __fish_git_prompt_char_untrackedfiles '%' '…' __fish_git_prompt_set_char __fish_git_prompt_char_upstream_ahead '>' '↑' __fish_git_prompt_set_char __fish_git_prompt_char_upstream_behind '<' '↓' From 6f3d7209c2bc46cc1a589b909e1b900847e0c59d Mon Sep 17 00:00:00 2001 From: Gennadiy Zlobin Date: Sun, 4 Aug 2013 14:53:00 +0400 Subject: [PATCH 034/170] Fixes broken link in docs. Fixes #943 --- doc_src/index.hdr.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc_src/index.hdr.in b/doc_src/index.hdr.in index 9b674479d..e9ff347e3 100644 --- a/doc_src/index.hdr.in +++ b/doc_src/index.hdr.in @@ -795,7 +795,7 @@ To set the variable \c smurf_color to the value \c blue, use the command set smurf_color blue. After a variable has been set, you can use the value of a variable in -the shell through variable expansion. +the shell through variable expansion. Example: From f30a5fe2888e57daf56b4d1d93fc7576f3bd43ac Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Tue, 30 Jul 2013 22:05:30 +0800 Subject: [PATCH 035/170] .gitignore: ignore generated source docs, don't ignore Doxyfile.help Doxyfile.help isn't generated --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a9fe03cbe..5247a0b85 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ *.o *~ -Doxyfile.help Makefile autom4te.cache/ build/ @@ -12,6 +11,7 @@ config.h.in config.log config.status configure +doc/ doc.h doc_src/commands.hdr doc_src/index.hdr From 969928e5008965e7d0114574274a533ef1f4fe42 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Wed, 31 Jul 2013 14:50:39 -0700 Subject: [PATCH 036/170] git_prompt: Fix bad test if bash.showUntrackedFiles isn't set --- share/functions/__fish_git_prompt.fish | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 610bdd6a5..64d7a748e 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -375,7 +375,8 @@ function __fish_git_prompt --description "Prompt function for Git" end if test -n "$__fish_git_prompt_showuntrackedfiles" - if test (git config --bool bash.showUntrackedFiles) != false + set -l config (git config --bool bash.showUntrackedFiles) + if test "$config" != false if git ls-files --others --exclude-standard --error-unmatch -- '*' >/dev/null ^/dev/null set u $___fish_git_prompt_char_untrackedfiles end From 0bf531624949bd79f6986622cd667881ccf1d13a Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Wed, 31 Jul 2013 15:25:29 -0700 Subject: [PATCH 037/170] git_prompt: Default upstream_prefix to nothing git.git's __git_ps1 doesn't have an upstream prefix. I'm not sure why one was added to our __fish_git_prompt, but it certainly shouldn't default to a space. --- share/functions/__fish_git_prompt.fish | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 64d7a748e..0515f16f6 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -155,8 +155,7 @@ # # The separator before the upstream information can be customized via # __fish_git_prompt_char_upstream_prefix. It is colored like the rest of -# the upstream information. It normallly defaults to a space ( ) and defaults -# to nothing () when __fish_git_prompt_show_informative_status is set. +# the upstream information. It defaults to nothing (). # # # Turning on __fish_git_prompt_showcolorhints changes the colors as follows to @@ -636,7 +635,7 @@ function __fish_git_prompt_validate_chars --description "__fish_git_prompt helpe __fish_git_prompt_set_char __fish_git_prompt_char_upstream_behind '<' '↓' __fish_git_prompt_set_char __fish_git_prompt_char_upstream_diverged '<>' __fish_git_prompt_set_char __fish_git_prompt_char_upstream_equal '=' - __fish_git_prompt_set_char __fish_git_prompt_char_upstream_prefix ' ' + __fish_git_prompt_set_char __fish_git_prompt_char_upstream_prefix '' end From b482cab7bea1f936f34eab6350f701f10f65784c Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Wed, 7 Aug 2013 11:18:31 +0800 Subject: [PATCH 038/170] docs: add editor documentation, move binding information closes #931 also fixes a crossreference error --- doc_src/bind.txt | 30 ++++++++++++++++++++++ doc_src/index.hdr.in | 61 ++++++++++++-------------------------------- 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/doc_src/bind.txt b/doc_src/bind.txt index add185a11..1e434b06a 100644 --- a/doc_src/bind.txt +++ b/doc_src/bind.txt @@ -46,6 +46,10 @@ bind to the function name. This way it becomes significantly easier to test the function while editing, and the result is usually more readable as well. +If such a script produces output, the script needs to finish by +calling 'commandline -f repaint' in order to tell fish that a repaint +is in order. + Key bindings are not saved between sessions by default. To save custom keybindings, edit the \c fish_user_key_bindings function and insert the appropriate \c bind statements. @@ -56,6 +60,32 @@ The following parameters are available: - -K or --key-names Display a list of available key names - -f or --function-names Display a list of available input functions +The following special input functions are available: + +- \c backward-char, moves one character to the left +- \c backward-delete-char, deletes one character of input to the left of the cursor +- \c backward-kill-line, move everything from the beginning of the line to the cursor to the killring +- \c backward-kill-word, move the word to the left of the cursor to the killring +- \c backward-word, move one word to the left +- \c beginning-of-history, move to the beginning of the history +- \c beginning-of-line, move to the beginning of the line +- \c complete, guess the remainder of the current token +- \c delete-char, delete one character to the right of the cursor +- \c delete-line, delete the entire line +- \c dump-functions, print a list of all key-bindings +- \c end-of-history, move to the end of the history +- \c end-of-line, move to the end of the line +- \c explain, print a description of possible problems with the current command +- \c forward-char, move one character to the right +- \c forward-word, move one word to the right +- \c history-search-backward, search the history for the previous match +- \c history-search-forward, search the history for the next match +- \c kill-line, move everything from the cursor to the end of the line to the killring +- \c kill-whole-line, move the line to the killring +- \c kill-word, move the next word to the killring +- \c yank, insert the latest entry of the killring into the buffer +- \c yank-pop, rotate to the previous entry of the killring + \subsection bind-example Examples bind \\cd 'exit' causes \c fish to exit when Control-d is pressed. diff --git a/doc_src/index.hdr.in b/doc_src/index.hdr.in index e9ff347e3..050452410 100644 --- a/doc_src/index.hdr.in +++ b/doc_src/index.hdr.in @@ -795,7 +795,7 @@ To set the variable \c smurf_color to the value \c blue, use the command set smurf_color blue. After a variable has been set, you can use the value of a variable in -the shell through variable expansion. +the shell through variable expansion. Example: @@ -1102,57 +1102,28 @@ shortcuts. Here are some of the commands available in the editor: -- Tab completes the current token -- Home or Ctrl-A moves to the beginning of the line -- End or Ctrl-E moves to the end of line -- Left and Right moves one character left or right -- Alt-Left and Alt-Right moves one word left or right, or moves forward/backward in the directory history if the commandline is empty +- Tab completes the current token. +- Home or Ctrl-A moves the cursor to the beginning of the line. +- End or Ctrl-E moves to the end of line. If the cursor is already at the end of the line, and an autosuggestion is available, End or Ctrl-E accepts the autosuggestion. +- Left (or Ctrl-B) and Right (or Ctrl-F) move the cursor left or right by one character. If the cursor is already at the end of the line, and an autosuggestion is available, the Right key and the Ctrl-F combination accept the suggestion. +- Alt-Left and Alt-Right move the cursor one word left or right, or moves forward/backward in the directory history if the command line is empty. - Up and Down search the command history for the previous/next command containing the string that was specified on the commandline before the search was started. If the commandline was empty when the search started, all commands match. See the history section for more information on history searching. - Alt-Up and Alt-Down search the command history for the previous/next token containing the token under the cursor before the search was started. If the commandline was not on a token when the search started, all tokens match. See the history section for more information on history searching. -- Delete and Backspace removes one character forwards or backwards respectively -- Ctrl-C deletes entire line -- Ctrl-D delete one character to the right of the cursor, unless the buffer is empty, in which case the shell will exit -- Ctrl-K moves contents from the cursor to the end of line to the killring -- Ctrl-U moves contents from the beginning of line to the cursor to the killring -- Ctrl-L clears and repaints the screen -- Ctrl-W moves the previous word to the killring -- Alt-D moves the next word to the killring -- Alt-W prints a short description of the command under the cursor -- Alt-L lists the contents of the current directory, unless the cursor is over a directory argument, in which case the contents of that directory will be listed +- Delete and Backspace removes one character forwards or backwards respectively. +- Ctrl-C deletes the entire line. +- Ctrl-D delete one character to the right of the cursor. If the command line is empty, Ctrl-D will exit fish. +- Ctrl-K moves contents from the cursor to the end of line to the killring. +- Ctrl-U moves contents from the beginning of line to the cursor to the killring. +- Ctrl-L clears and repaints the screen. +- Ctrl-W moves the previous word to the killring. +- Alt-D moves the next word to the killring. +- Alt-W prints a short description of the command under the cursor. +- Alt-L lists the contents of the current directory, unless the cursor is over a directory argument, in which case the contents of that directory will be listed. - Alt-P adds the string '| less;' to the end of the job under the cursor. The result is that the output of the command will be paged. You can change these key bindings using the bind builtin command. - -- \c backward-char, moves one character to the left -- \c backward-delete-char, deletes one character of input to the left of the cursor -- \c backward-kill-line, move everything from the beginning of the line to the cursor to the killring -- \c backward-kill-word, move the word to the left of the cursor to the killring -- \c backward-word, move one word to the left -- \c beginning-of-history, move to the beginning of the history -- \c beginning-of-line, move to the beginning of the line -- \c complete, guess the remainder of the current token -- \c delete-char, delete one character to the right of the cursor -- \c delete-line, delete the entire line -- \c dump-functions, print a list of all key-bindings -- \c end-of-history, move to the end of the history -- \c end-of-line, move to the end of the line -- \c explain, print a description of possible problems with the current command -- \c forward-char, move one character to the right -- \c forward-word, move one word to the right -- \c history-search-backward, search the history for the previous match -- \c history-search-forward, search the history for the next match -- \c kill-line, move everything from the cursor to the end of the line to the killring -- \c kill-whole-line, move the line to the killring -- \c kill-word, move the next word to the killring -- \c yank, insert the latest entry of the killring into the buffer -- \c yank-pop, rotate to the previous entry of the killring - -If such a script produces output, the script needs to finish by -calling 'commandline -f repaint' in order to tell fish that a repaint -is in order. - \subsection killring Copy and paste (Kill Ring) \c fish uses an Emacs style kill ring for copy and paste From ed8ff85d2aec6b33be43faee5e85c1272bb1d4d0 Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Wed, 7 Aug 2013 11:26:57 +0800 Subject: [PATCH 039/170] accidentally reopened #943, fixed now --- doc_src/index.hdr.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc_src/index.hdr.in b/doc_src/index.hdr.in index 050452410..26fc56967 100644 --- a/doc_src/index.hdr.in +++ b/doc_src/index.hdr.in @@ -795,7 +795,7 @@ To set the variable \c smurf_color to the value \c blue, use the command set smurf_color blue. After a variable has been set, you can use the value of a variable in -the shell through variable expansion. +the shell through variable expansion. Example: From 625a1cb0b57112c4ce84c665a16c0fee364c49f8 Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Mon, 24 Jun 2013 18:06:12 +0800 Subject: [PATCH 040/170] .gitattributes: mark most scripts in build_tools as not for export (but not all!) build_documentation.sh is needed for the tarball if you run make distclean --- .gitattributes | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 6f346fba8..94ef0ab2d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,20 @@ .gitattributes export-ignore .gitignore export-ignore -/build_tools export-ignore +/build_tools/make_svn_completions.fish export-ignore +/build_tools/description-pak export-ignore +/build_tools/make_hg_completions.fish export-ignore +/build_tools/make_vcs_completions.fish export-ignore +/build_tools/make_vcs_completions_generic.fish export-ignore +/build_tools/osx_package_resources export-ignore +/build_tools/osx_package_resources/terminal_logo.png export-ignore +/build_tools/osx_package_resources/welcome.rtf export-ignore +/build_tools/make_csv_completions.fish export-ignore +/build_tools/osx_distribution.xml export-ignore +/build_tools/make_tarball.sh export-ignore +/build_tools/make_deb.sh export-ignore +/build_tools/osx_package_scripts export-ignore +/build_tools/osx_package_scripts/add-shell export-ignore +/build_tools/osx_package_scripts/postinstall export-ignore +/build_tools/make_pkg.sh export-ignore +/build_tools/make_darcs_completions.fish export-ignore From 05563ab11ee30fbf698c0bbfcb9f98e2533a0a1d Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Mon, 24 Jun 2013 18:09:29 +0800 Subject: [PATCH 041/170] add git_version_gen: generate a version number from the git tree Originally from the git sources (GIT-VERSION-GEN) (C) Junio C Hamano Reused under GPL v2.0 --- .gitignore | 1 + build_tools/git_version_gen.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100755 build_tools/git_version_gen.sh diff --git a/.gitignore b/.gitignore index 5247a0b85..b4b4e81c9 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ user_doc/ xcuserdata tests/*tmp.* tests/foo.txt +FISH-BUILD-VERSION-FILE diff --git a/build_tools/git_version_gen.sh b/build_tools/git_version_gen.sh new file mode 100755 index 000000000..5a54eb3be --- /dev/null +++ b/build_tools/git_version_gen.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# Originally from the git sources (GIT-VERSION-GEN) +# Presumably (C) Junio C Hamano +# Reused under GPL v2.0 +# Modified for fish by David Adam + +FBVF=FISH-BUILD-VERSION-FILE +DEF_VER=2.0.GIT + +# First see if there is a version file (included in release tarballs), +# then try git-describe, then default. +if test -f version +then + VN=$(cat version) || VN="$DEF_VER" +elif test -d .git -o -f .git && which git >/dev/null +then + VN=$(git describe --tags --dirty 2>/dev/null) +else + VN="$DEF_VER" +fi + +if test -r $FBVF +then + VC=$(sed -e 's/^FISH_BUILD_VERSION = //' <$FBVF) +else + VC=unset +fi +test "$VN" = "$VC" || { + echo >&2 "FISH_BUILD_VERSION = $VN" + echo "FISH_BUILD_VERSION = $VN" >$FBVF +} From 2a06c72113fb4a7032621387751d5c9c945936ae Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Mon, 24 Jun 2013 18:12:09 +0800 Subject: [PATCH 042/170] Generate version numbers dynamically This commit hooks the Makefile up to generate a FISH_BUILD_VERSION symbol and kills off PACKAGE_VERSION in .cpp files. It also modifies the tarball generation script to add the necessary version file for releases. --- Makefile.in | 16 ++++++++++++++-- build_tools/make_tarball.sh | 7 ++++++- env.cpp | 2 +- fish.cpp | 2 +- fish_indent.cpp | 2 +- fish_pager.cpp | 2 +- fishd.cpp | 2 +- mimedb.cpp | 2 +- 8 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Makefile.in b/Makefile.in index 9db4aa47d..7cbd159d3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -282,6 +282,17 @@ all: $(PROGRAMS) $(user_doc) share/man $(TRANSLATIONS) @echo Use \'$(MAKE) install\' to install fish. .PHONY: all +# +# Pull version information +# + +FISH-BUILD-VERSION-FILE: FORCE + @./build_tools/git_version_gen.sh +-include FISH-BUILD-VERSION-FILE +CPPFLAGS += -DFISH_BUILD_VERSION=\"$(FISH_BUILD_VERSION)\" +.PHONY: FORCE +env.o fish.o fish_indent.o fish_pager.o fishd.o mimedb.o: FISH-BUILD-VERSION-FILE + # # These dependencies make sure that autoconf and configure are run @@ -313,7 +324,7 @@ prof: all # intermediate *.hdr and doc.h files if needed user_doc: $(HDR_FILES_SRC) Doxyfile.user user_doc.head.html $(HELP_SRC) doc.h $(HDR_FILES) - (cat Doxyfile.user ; echo PROJECT_NUMBER=@PACKAGE_VERSION@) | doxygen - && touch user_doc + (cat Doxyfile.user ; echo PROJECT_NUMBER=$(FISH_BUILD_VERSION)) | doxygen - && touch user_doc # @@ -321,7 +332,7 @@ user_doc: $(HDR_FILES_SRC) Doxyfile.user user_doc.head.html $(HELP_SRC) doc.h $( # doc: *.h *.cpp doc.h Doxyfile - (cat Doxyfile ; echo PROJECT_NUMBER=@PACKAGE_VERSION@) | doxygen - ; + (cat Doxyfile ; echo PROJECT_NUMBER=$(FISH_BUILD_VERSION)) | doxygen - ; # @@ -849,6 +860,7 @@ clean: rm -f $(PROGRAMS) fish_tests key_reader rm -f command_list.txt toc.txt rm -f doc_src/index.hdr doc_src/commands.hdr + rm -f FISH-BUILD-VERSION-FILE rm -f fish-@PACKAGE_VERSION@.tar rm -f fish-@PACKAGE_VERSION@.tar.gz rm -f fish-@PACKAGE_VERSION@.tar.bz2 diff --git a/build_tools/make_tarball.sh b/build_tools/make_tarball.sh index b74fc9c4e..183ea2a14 100755 --- a/build_tools/make_tarball.sh +++ b/build_tools/make_tarball.sh @@ -19,8 +19,11 @@ wd="$PWD" # The name of the prefix, which is the directory that you get when you untar prefix="fish" +# Get the version from git-describe +VERSION=`git describe --tags --dirty 2>/dev/null` + # The path where we will output the tar file -path=~/fish_built/fish-2.0.tar +path=~/fish_built/fish-$VERSION.tar # Clean up stuff we've written before rm -f "$path" "$path".gz @@ -31,11 +34,13 @@ git archive --format=tar --prefix="$prefix"/ master > "$path" # tarball out the documentation make user_doc make share/man +echo $VERSION > version cd /tmp rm -f "$prefix" ln -s "$wd" "$prefix" gnutar --append --file="$path" "$prefix"/user_doc/html gnutar --append --file="$path" "$prefix"/share/man +gnutar --append --file="$path" "$prefix"/version rm -f "$prefix" # gzip it diff --git a/env.cpp b/env.cpp index ddb5d2c4e..a99f18121 100644 --- a/env.cpp +++ b/env.cpp @@ -667,7 +667,7 @@ void env_init(const struct config_paths_t *paths /* or NULL */) /* Set up the version variables */ - wcstring version = str2wcstring(PACKAGE_VERSION); + wcstring version = str2wcstring(FISH_BUILD_VERSION); env_set(L"version", version.c_str(), ENV_GLOBAL); env_set(L"FISH_VERSION", version.c_str(), ENV_GLOBAL); diff --git a/fish.cpp b/fish.cpp index 8001f3764..fda24360c 100644 --- a/fish.cpp +++ b/fish.cpp @@ -350,7 +350,7 @@ static int fish_parse_opt(int argc, char **argv, std::vector *out_c fwprintf(stderr, _(L"%s, version %s\n"), PACKAGE_NAME, - PACKAGE_VERSION); + FISH_BUILD_VERSION); exit_without_destructors(0); } diff --git a/fish_indent.cpp b/fish_indent.cpp index db48679b4..3b54d008d 100644 --- a/fish_indent.cpp +++ b/fish_indent.cpp @@ -344,7 +344,7 @@ int main(int argc, char **argv) fwprintf(stderr, _(L"%ls, version %s\n"), program_name, - PACKAGE_VERSION); + FISH_BUILD_VERSION); exit(0); } diff --git a/fish_pager.cpp b/fish_pager.cpp index 2e1a4bbaa..848eb0fc0 100644 --- a/fish_pager.cpp +++ b/fish_pager.cpp @@ -1289,7 +1289,7 @@ int main(int argc, char **argv) case 'v': { - debug(0, L"%ls, version %s\n", program_name, PACKAGE_VERSION); + debug(0, L"%ls, version %s\n", program_name, FISH_BUILD_VERSION); exit(0); } diff --git a/fishd.cpp b/fishd.cpp index 638e17622..e5edc3da5 100644 --- a/fishd.cpp +++ b/fishd.cpp @@ -922,7 +922,7 @@ int main(int argc, char ** argv) exit(0); case 'v': - debug(0, L"%ls, version %s\n", program_name, PACKAGE_VERSION); + debug(0, L"%ls, version %s\n", program_name, FISH_BUILD_VERSION); exit(0); case '?': diff --git a/mimedb.cpp b/mimedb.cpp index 9b66bb0a2..fdf5da12d 100644 --- a/mimedb.cpp +++ b/mimedb.cpp @@ -1332,7 +1332,7 @@ int main(int argc, char *argv[]) exit(0); case 'v': - printf(_("%s, version %s\n"), MIMEDB, PACKAGE_VERSION); + printf(_("%s, version %s\n"), MIMEDB, FISH_BUILD_VERSION); exit(0); case '?': From 8cdcfc2a911a2fe3281cbf91351d817416a9d936 Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Mon, 24 Jun 2013 18:15:47 +0800 Subject: [PATCH 043/170] configure.ac: generate the fish version number dynamically Note that this will NOT get updated on every run - even if autoconf is run manually, the value may be cached. The PACKAGE_VERSION variable/symbol will not be reliable. Use FISH_BUILD_VERSION instead. --- configure.ac | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 185fc96b2..fb260eb55 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,11 @@ # configure the build process. # -AC_INIT(fish,2.0.0,fish-users@lists.sf.net) +m4_syscmd([build_tools/git_version_gen.sh 2>/dev/null]) + +AC_INIT(fish, + m4_esyscmd_s([cut -f 3 -d ' ' FISH-BUILD-VERSION-FILE]), + fish-users@lists.sf.net) conf_arg=$@ From 75fe438f21f60243fcf6682b659f8d0054e6fc92 Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Fri, 26 Jul 2013 09:51:58 +0800 Subject: [PATCH 044/170] osx/config.h: define the FISH_BUILD_VERSION symbol --- osx/config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/osx/config.h b/osx/config.h index 9872a2e12..417dec68b 100644 --- a/osx/config.h +++ b/osx/config.h @@ -193,6 +193,7 @@ /* Define to the version of this package. */ #define PACKAGE_VERSION "2.0.0" +#define FISH_BUILD_VERSION PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 From b1d8492c3f706d2d1a234eabaed2426fc67dc488 Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Tue, 30 Jul 2013 22:09:12 +0800 Subject: [PATCH 045/170] Makefile.in: don't build dist stuff from Makefile, use build_tools --- Makefile.in | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/Makefile.in b/Makefile.in index 7cbd159d3..4d24e588a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -788,19 +788,6 @@ depend: ./config.status .PHONY: depend -# -# Make compressed tar archives -# - -fish-@PACKAGE_VERSION@.tar.gz: fish-@PACKAGE_VERSION@.tar - gzip -f --best -c fish-@PACKAGE_VERSION@.tar >fish-@PACKAGE_VERSION@.tar.gz - -fish-@PACKAGE_VERSION@.tar.bz2: fish-@PACKAGE_VERSION@.tar - bzip2 -f --best -k fish-@PACKAGE_VERSION@.tar - -dist: fish-@PACKAGE_VERSION@.tar.bz2 -.PHONY: dist - # # Build the RPM spec file. # @@ -808,28 +795,6 @@ dist: fish-@PACKAGE_VERSION@.tar.bz2 fish.spec: fish.spec.in ./config.status - - -# -# Create .rpm file for the current systems architecture and an -# .src.rpm file. -# - -rpm: fish-@PACKAGE_VERSION@.tar.bz2 fish.spec - @if which rpmbuild; then true; else \ - echo Could not find the rpmbuild command, needed to build an rpm; \ - echo You may be able to install it using the following command:; \ - echo \'yum install rpm-build\'; \ - false; \ - fi - cp fish.spec /usr/src/redhat/SPECS/ - cp fish-@PACKAGE_VERSION@.tar.bz2 /usr/src/redhat/SOURCES/ - rpmbuild -ba --clean /usr/src/redhat/SPECS/fish.spec - mv /usr/src/redhat/RPMS/*/fish*@PACKAGE_VERSION@*.rpm . - mv /usr/src/redhat/SRPMS/fish*@PACKAGE_VERSION@*.src.rpm . -.PHONY: rpm - - # # Cleanup targets # @@ -861,13 +826,9 @@ clean: rm -f command_list.txt toc.txt rm -f doc_src/index.hdr doc_src/commands.hdr rm -f FISH-BUILD-VERSION-FILE - rm -f fish-@PACKAGE_VERSION@.tar - rm -f fish-@PACKAGE_VERSION@.tar.gz - rm -f fish-@PACKAGE_VERSION@.tar.bz2 if test $(HAVE_DOXYGEN) = 1; then \ rm -rf doc user_doc share/man; \ fi - rm -rf fish-@PACKAGE_VERSION@ rm -f $(TRANSLATIONS) .PHONY: clean From a00b979bb6050e36dcca06708533492b26345f9f Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Sun, 11 Aug 2013 23:23:28 +0800 Subject: [PATCH 046/170] tarball contents should match the filename --- build_tools/make_tarball.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build_tools/make_tarball.sh b/build_tools/make_tarball.sh index 183ea2a14..77d78c67e 100755 --- a/build_tools/make_tarball.sh +++ b/build_tools/make_tarball.sh @@ -21,9 +21,10 @@ prefix="fish" # Get the version from git-describe VERSION=`git describe --tags --dirty 2>/dev/null` +prefix="$prefix-$VERSION" # The path where we will output the tar file -path=~/fish_built/fish-$VERSION.tar +path=~/fish_built/$prefix.tar # Clean up stuff we've written before rm -f "$path" "$path".gz From ada3ab4213e8acb421729f954025e608e738276c Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Sun, 11 Aug 2013 23:45:39 +0800 Subject: [PATCH 047/170] .gitignore: ignore tarball files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b4b4e81c9..57cd62b34 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ xcuserdata tests/*tmp.* tests/foo.txt FISH-BUILD-VERSION-FILE +version From 79d5ff03502b779fde4994ab65dd22c049d8125b Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Mon, 12 Aug 2013 09:38:17 +0300 Subject: [PATCH 048/170] Fix ls command under Cygwin It appears that dircolors -c under Cygwin has >&/dev/null at end that is valid C shell syntax, but isn't accepted in fish shell. --- share/functions/ls.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/functions/ls.fish b/share/functions/ls.fish index 1db746226..dd4fb3a67 100644 --- a/share/functions/ls.fish +++ b/share/functions/ls.fish @@ -14,7 +14,7 @@ if command ls --version 1>/dev/null 2>/dev/null if not set -q LS_COLORS if type -f dircolors >/dev/null - eval (dircolors -c) + eval (dircolors -c | sed 's/>&\/dev\/null$//') end end From 64921fe08a35aedc2715471b45b78d583660ddb7 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Mon, 12 Aug 2013 09:56:03 +0300 Subject: [PATCH 049/170] Fix hostname command under Cygwin with Unicode characters Yes, hostname is broken under Cygwin, but for fish it's an issue, as it makes fish_config more buggy than it needs to be (by making UTF-8 errors according to Python). --- share/functions/hostname.fish | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 share/functions/hostname.fish diff --git a/share/functions/hostname.fish b/share/functions/hostname.fish new file mode 100644 index 000000000..eb667ef85 --- /dev/null +++ b/share/functions/hostname.fish @@ -0,0 +1,8 @@ +# Query for USERDOMAIN to shorten waiting times when OS isn't Windows. +if set -q USERDOMAIN; and test (uname -o) = Cygwin + # Cygwin's hostname is broken when computer name contains Unicode + # characters. This hack "fixes" hostname in Cygwin. + function hostname --description "Show or set the system's host name" + echo $USERDOMAIN + end +end From e5e7da148267f2fe07df88b762df286dc0448da6 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Mon, 12 Aug 2013 09:58:45 +0300 Subject: [PATCH 050/170] Ignore executable files I commited executables in previous commit (removed using git push --force - sorry, I wouldn't want to waste space in git repository), so I think *.exe files should be forbidden to avoid any problems (there is no reason to ever commit them) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 57cd62b34..b2ea73dc2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.o *~ +*.exe Makefile autom4te.cache/ From d7c68559188410f61a2f6161527fbf75c9e5dccb Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Mon, 12 Aug 2013 20:19:51 +0300 Subject: [PATCH 051/170] Remove problems with fishd under Cygwin. Yes, it's an awful hack, but IPC support (and fork support as well - even FAQ mentions that, and suggests "restarting process" to solve the problem (http://cygwin.com/faq/faq.html#faq.using.fixing-fork-failures), but let's ignore that for now) is simply broken in Cygwin. Having to try to do exactly same thing in Cygwin, just so perhaps it will work is a completely normal thing (not). I love Windows. --- fishd.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fishd.cpp b/fishd.cpp index e5edc3da5..edb79c22f 100644 --- a/fishd.cpp +++ b/fishd.cpp @@ -529,6 +529,14 @@ static bool acquire_socket_lock(const std::string &sock_name, std::string *out_l */ static int get_socket(void) { + // Cygwin has random problems involving sockets. When using Cygwin, + // allow 20 attempts at making socket correctly. +#ifdef __CYGWIN__ + int attempts = 0; +repeat: + attempts += 1; +#endif + int s, len, doexit = 0; int exitcode = EXIT_FAILURE; struct sockaddr_un local; @@ -599,6 +607,10 @@ unlock: if (doexit) { + // If Cygwin, only allow normal quit when made lots of attempts. +#ifdef __CYGWIN__ + if (exitcode && attempts < 20) goto repeat; +#endif exit_without_destructors(exitcode); } From 4388b73077814a8ae45429bfa70f0b9c013c0547 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Tue, 13 Aug 2013 17:07:24 +0300 Subject: [PATCH 052/170] Don't mention chsh if it doesn't exist. This is case in Cygwin, which doesn't have /etc/shells ans chsh. --- Makefile.in | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile.in b/Makefile.in index 4d24e588a..745628e6c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -640,9 +640,11 @@ install-force: all install-translations @echo fish is now installed on your system. @echo To run fish, type \'fish\' in your terminal. @echo - @echo To use fish as your login shell: - @grep -q -- "$(DESTDIR)$(bindir)/fish" /etc/shells || echo \* add the line \'$(DESTDIR)$(bindir)/fish\' to the file \'/etc/shells\'. - @echo \* use the command \'chsh -s $(DESTDIR)$(bindir)/fish\'. + if type chsh &> /dev/null; then \ + echo To use fish as your login shell:; \ + grep -q -- "$(DESTDIR)$(bindir)/fish" /etc/shells || echo \* add the line \'$(DESTDIR)$(bindir)/fish\' to the file \'/etc/shells\'.; \ + echo \* use the command \'chsh -s $(DESTDIR)$(bindir)/fish\'.; \ + fi; @echo @echo To set your colors, run \'fish_config\' @echo To scan your man pages for completions, run \'fish_update_completions\' From 07c48590c0588abb2a8a6d174d6fde42b97216e4 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Tue, 13 Aug 2013 17:13:18 +0300 Subject: [PATCH 053/170] Be quiet about "if" conditional. --- Makefile.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.in b/Makefile.in index 745628e6c..3c0eeffe2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -640,12 +640,12 @@ install-force: all install-translations @echo fish is now installed on your system. @echo To run fish, type \'fish\' in your terminal. @echo - if type chsh &> /dev/null; then \ + @if type chsh &> /dev/null; then \ echo To use fish as your login shell:; \ grep -q -- "$(DESTDIR)$(bindir)/fish" /etc/shells || echo \* add the line \'$(DESTDIR)$(bindir)/fish\' to the file \'/etc/shells\'.; \ echo \* use the command \'chsh -s $(DESTDIR)$(bindir)/fish\'.; \ + echo; \ fi; - @echo @echo To set your colors, run \'fish_config\' @echo To scan your man pages for completions, run \'fish_update_completions\' @echo To autocomplete command suggestions press Ctrl + F or right arrow key. From 4fc2ee1bd402eadc0e7f92b0c48761c46dcd4a5a Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Tue, 13 Aug 2013 17:21:40 +0300 Subject: [PATCH 054/170] Implement 'open' for Cygwin. --- share/functions/open.fish | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/share/functions/open.fish b/share/functions/open.fish index 885079e11..63d562371 100644 --- a/share/functions/open.fish +++ b/share/functions/open.fish @@ -14,7 +14,11 @@ if not test (uname) = Darwin end end - if type -f xdg-open >/dev/null + if type -f cygstart >/dev/null + for i in $argv + cygstart $i + end + else if type -f xdg-open >/dev/null for i in $argv xdg-open $i end From 8ab81e6d4b24c965ea0f7191a29e332f803df4ba Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Tue, 13 Aug 2013 17:26:38 +0300 Subject: [PATCH 055/170] Implement 'help' for Cygwin. --- share/functions/help.fish | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/share/functions/help.fish b/share/functions/help.fish index ef147e722..04992e35d 100644 --- a/share/functions/help.fish +++ b/share/functions/help.fish @@ -54,8 +54,11 @@ function help --description 'Show help for the fish shell' end end + # If the OS appears to be Windows (graphical), try to use cygstart + if type cygstart > /dev/null + set fish_browser cygstart # If xdg-open is available, just use that - if type xdg-open > /dev/null + else if type xdg-open > /dev/null set fish_browser xdg-open end From feb36e7342cf782e7723fe41eb2c414ec2879800 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Wed, 14 Aug 2013 12:11:09 +0300 Subject: [PATCH 056/170] Show drive letter under Cygwin /c/c looks awful, and C:/ is simply better. --- share/functions/prompt_pwd.fish | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/share/functions/prompt_pwd.fish b/share/functions/prompt_pwd.fish index 716372f42..ed6eb3d91 100644 --- a/share/functions/prompt_pwd.fish +++ b/share/functions/prompt_pwd.fish @@ -2,6 +2,10 @@ if test (uname) = Darwin function prompt_pwd --description "Print the current working directory, shortend to fit the prompt" echo $PWD | sed -e "s|^$HOME|~|" -e 's|^/private||' -e 's-\([^/.]\)[^/]*/-\1/-g' end +else if test (uname -o) = Cygwin + function prompt_pwd --description "Print the current working directory, shortend to fit the prompt" + echo $PWD | sed -e "s|^$HOME|~|" -e 's|^/cygdrive/\(.\)|\1/:|' -e 's-\([^/.]\)[^/]*/-\1/-g' -e 's-^\([^/]\)/:/\?-\u\1:/-' + end else function prompt_pwd --description "Print the current working directory, shortend to fit the prompt" echo $PWD | sed -e "s|^$HOME|~|" -e 's-\([^/.]\)[^/]*/-\1/-g' From d407d680eaea4afb9eef384a003b10c5f6aafcd7 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Wed, 14 Aug 2013 12:21:17 +0300 Subject: [PATCH 057/170] Show path containing current disk drive in Windows in title --- reader.cpp | 4 ++-- share/functions/__fish_pwd.fish | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 share/functions/__fish_pwd.fish diff --git a/reader.cpp b/reader.cpp index 7753bd759..0e5b45bd4 100644 --- a/reader.cpp +++ b/reader.cpp @@ -111,7 +111,7 @@ commence. fish specific commands, meaning it will work even if fish is not installed. This is used by read_i. */ -#define DEFAULT_PROMPT L"echo -n \"$USER@\"(hostname|cut -d . -f 1)' '(pwd)'> '" +#define DEFAULT_PROMPT L"echo -n \"$USER@\"(hostname|cut -d . -f 1)' '(__fish_pwd)'> '" /** The name of the function that prints the fish prompt @@ -127,7 +127,7 @@ commence. /** The default title for the reader. This is used by reader_readline. */ -#define DEFAULT_TITLE L"echo $_ \" \"; pwd" +#define DEFAULT_TITLE L"echo $_ \" \"; __fish_pwd" /** The maximum number of characters to read from the keyboard without diff --git a/share/functions/__fish_pwd.fish b/share/functions/__fish_pwd.fish new file mode 100644 index 000000000..d072c6fab --- /dev/null +++ b/share/functions/__fish_pwd.fish @@ -0,0 +1,9 @@ +if test (uname -o) = Cygwin + function __fish_pwd --description "Show current path" + pwd | sed -e 's-^/cygdrive/\(.\)/\?-\u\1:/-' + end +else + function __fish_pwd --description "Show current path" + pwd + end +end \ No newline at end of file From 5818289c2da8e53b8b52b69064254576ba7d839a Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Wed, 14 Aug 2013 18:43:09 +0300 Subject: [PATCH 058/170] Deprecate "." command. Fixes #310. Needs documentation (for the new name), but manages to move . to source, while preserving compatibility. --- builtin.cpp | 6 +++--- fish.cpp | 6 +++--- share/config.fish | 13 +++++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/builtin.cpp b/builtin.cpp index d230080a4..d01322e21 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -3014,7 +3014,7 @@ static int builtin_source(parser_t &parser, wchar_t ** argv) if ((fd = wopen_cloexec(argv[1], O_RDONLY)) == -1) { append_format(stderr_buffer, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1]); - builtin_wperror(L"."); + builtin_wperror(L"source"); return STATUS_BUILTIN_ERROR; } @@ -3022,7 +3022,7 @@ static int builtin_source(parser_t &parser, wchar_t ** argv) { close(fd); append_format(stderr_buffer, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1]); - builtin_wperror(L"."); + builtin_wperror(L"source"); return STATUS_BUILTIN_ERROR; } @@ -3953,7 +3953,6 @@ static int builtin_history(parser_t &parser, wchar_t **argv) */ static const builtin_data_t builtin_datas[]= { - { L".", &builtin_source, N_(L"Evaluate contents of file") }, { L"[", &builtin_test, N_(L"Test a condition") }, { L"and", &builtin_generic, N_(L"Execute command if previous command suceeded") }, { L"begin", &builtin_begin, N_(L"Create a block of code") }, @@ -3993,6 +3992,7 @@ static const builtin_data_t builtin_datas[]= { L"return", &builtin_return, N_(L"Stop the currently evaluated function") }, { L"set", &builtin_set, N_(L"Handle environment variables") }, { L"set_color", &builtin_set_color, N_(L"Set the terminal color") }, + { L"source", &builtin_source, N_(L"Evaluate contents of file") }, { L"status", &builtin_status, N_(L"Return status information about fish") }, { L"switch", &builtin_switch, N_(L"Conditionally execute a block of commands") }, { L"test", &builtin_test, N_(L"Test a condition") }, diff --git a/fish.cpp b/fish.cpp index fda24360c..2251d8ecb 100644 --- a/fish.cpp +++ b/fish.cpp @@ -217,8 +217,8 @@ static int read_init(const struct config_paths_t &paths) { parser_t &parser = parser_t::principal_parser(); const io_chain_t empty_ios; - parser.eval(L"builtin . " + paths.data + L"/config.fish 2>/dev/null", empty_ios, TOP); - parser.eval(L"builtin . " + paths.sysconf + L"/config.fish 2>/dev/null", empty_ios, TOP); + parser.eval(L"builtin source " + paths.data + L"/config.fish 2>/dev/null", empty_ios, TOP); + parser.eval(L"builtin source " + paths.sysconf + L"/config.fish 2>/dev/null", empty_ios, TOP); /* @@ -233,7 +233,7 @@ static int read_init(const struct config_paths_t &paths) if (path_get_config(config_dir)) { wcstring config_dir_escaped = escape_string(config_dir, 1); - wcstring eval_buff = format_string(L"builtin . %ls/config.fish 2>/dev/null", config_dir_escaped.c_str()); + wcstring eval_buff = format_string(L"builtin source %ls/config.fish 2>/dev/null", config_dir_escaped.c_str()); parser.eval(eval_buff, empty_ios, TOP); } diff --git a/share/config.fish b/share/config.fish index 056fd34f7..e0b07bf9e 100644 --- a/share/config.fish +++ b/share/config.fish @@ -109,3 +109,16 @@ function __fish_on_interactive --on-event fish_prompt functions -e __fish_on_interactive end +# "." command for compatibility with old fish versions. +function . --description 'Evaluate contents of file (deprecated, see "source")' + if begin + test (count $argv) -eq 0 + # Uses tty directly, as isatty depends on "." + and tty 0>&0 >/dev/null + end + echo "source: '.' command is deprecated, and doesn't work with STDIN anymore. Did you mean 'source' or './'?" >&2 + return 1 + else + source $argv + end +end From 679ef952570f737ce92c49d976c2fd0eaf8f8c8c Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Wed, 14 Aug 2013 18:55:15 +0300 Subject: [PATCH 059/170] Document source command. --- doc_src/source.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc_src/source.txt b/doc_src/source.txt index 069583754..c49e24912 100644 --- a/doc_src/source.txt +++ b/doc_src/source.txt @@ -1,11 +1,11 @@ -\section source . - evaluate contents of file. +\section source source - evaluate contents of file. \subsection source-synopsis Synopsis -. FILENAME [ARGUMENTS...] +source FILENAME [ARGUMENTS...] \subsection source-description Description -\c . (source) evaluates the commands of the specified file in the current +\c source evaluates the commands of the specified file in the current shell. This is different from starting a new process to perform the commands (i.e. fish < FILENAME) since the commands will be evaluated by the current shell, which means that changes in @@ -16,11 +16,11 @@ variable. If no file is specified, or if the file name '-' is used, stdin will be read. -The return status of \c . is the return status of the last job to +The return status of \c source is the return status of the last job to execute. If something goes wrong while opening or reading the file, -\c . exits with a non-zero status. +\c source exits with a non-zero status. \subsection source-example Example -. ~/.config/fish/config.fish causes fish to re-read its initialization file. +source ~/.config/fish/config.fish causes fish to re-read its initialization file. From 6ec4591f02953963b5f4ad537184c66baf903f51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikko=20Viitam=C3=A4ki?= Date: Fri, 16 Aug 2013 11:45:15 +0300 Subject: [PATCH 060/170] fixing small typo --- doc_src/bind.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc_src/bind.txt b/doc_src/bind.txt index 1e434b06a..d7d17044f 100644 --- a/doc_src/bind.txt +++ b/doc_src/bind.txt @@ -17,7 +17,7 @@ an escape character, Alt-based key bindings can be written using the using the \c \\c escape, for example Control-x (^X) can be written as \\cx. Note that Alt-based key bindings are case sensitive and Control-based key bindings are not. This is a constraint of text-based -termainls, not \c fish. +terminals, not \c fish. The default key binding can be set by specifying a SEQUENCE of the empty string (that is, ''). It will be used whenever no From ca8e4c08a786f31f2ca2d353f54df3653fdd7a1a Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Fri, 16 Aug 2013 19:59:16 +0200 Subject: [PATCH 061/170] Fix compilation under CentOS I hope I didn't broke anything, but it works for me. --- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index fb260eb55..d7fa14829 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,3 @@ - # # This file is the main build configuration file for fish. It is used # to determine your systems capabilities, and tries to adapt fish to @@ -9,6 +8,8 @@ # configure the build process. # +m4_pattern_allow(m4_esyscmd_s) + m4_syscmd([build_tools/git_version_gen.sh 2>/dev/null]) AC_INIT(fish, From 3e115b7a85184d16a5bb8d00fff702a62e3f8fea Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Fri, 16 Aug 2013 20:47:04 +0200 Subject: [PATCH 062/170] Mac OS X doesn't support uname -o. Use uname instead. I break compatibility with Mac OS X again, that I don't have access to. Result: Stuff break, and I have to fix it, so it will perhaps work. At least, I hope it will work. --- share/functions/__fish_pwd.fish | 5 +++-- share/functions/hostname.fish | 4 +++- share/functions/prompt_pwd.fish | 7 ++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/share/functions/__fish_pwd.fish b/share/functions/__fish_pwd.fish index d072c6fab..282728715 100644 --- a/share/functions/__fish_pwd.fish +++ b/share/functions/__fish_pwd.fish @@ -1,8 +1,9 @@ -if test (uname -o) = Cygwin +switch (uname) +case 'CYGWIN_*' function __fish_pwd --description "Show current path" pwd | sed -e 's-^/cygdrive/\(.\)/\?-\u\1:/-' end -else +case '*' function __fish_pwd --description "Show current path" pwd end diff --git a/share/functions/hostname.fish b/share/functions/hostname.fish index eb667ef85..8caaca7cc 100644 --- a/share/functions/hostname.fish +++ b/share/functions/hostname.fish @@ -1,5 +1,7 @@ # Query for USERDOMAIN to shorten waiting times when OS isn't Windows. -if set -q USERDOMAIN; and test (uname -o) = Cygwin +set -q USERDOMAIN +and switch (uname) +case 'CYGWIN_*' # Cygwin's hostname is broken when computer name contains Unicode # characters. This hack "fixes" hostname in Cygwin. function hostname --description "Show or set the system's host name" diff --git a/share/functions/prompt_pwd.fish b/share/functions/prompt_pwd.fish index ed6eb3d91..f559fb046 100644 --- a/share/functions/prompt_pwd.fish +++ b/share/functions/prompt_pwd.fish @@ -1,12 +1,13 @@ -if test (uname) = Darwin +switch (uname) +case Darwin function prompt_pwd --description "Print the current working directory, shortend to fit the prompt" echo $PWD | sed -e "s|^$HOME|~|" -e 's|^/private||' -e 's-\([^/.]\)[^/]*/-\1/-g' end -else if test (uname -o) = Cygwin +case 'CYGWIN_*' function prompt_pwd --description "Print the current working directory, shortend to fit the prompt" echo $PWD | sed -e "s|^$HOME|~|" -e 's|^/cygdrive/\(.\)|\1/:|' -e 's-\([^/.]\)[^/]*/-\1/-g' -e 's-^\([^/]\)/:/\?-\u\1:/-' end -else +case '*' function prompt_pwd --description "Print the current working directory, shortend to fit the prompt" echo $PWD | sed -e "s|^$HOME|~|" -e 's-\([^/.]\)[^/]*/-\1/-g' end From d371af05040386110db32850ca4698e642c484dc Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Sat, 17 Aug 2013 10:47:35 +0800 Subject: [PATCH 063/170] configure.ac: remove m4_esyscmd_s m4_esyscmd_s is a macro only available in Autoconf 2.64, which despite being released in 2009 is not available on a number of build targets for the project (specifically CentOS/RHEL 6). ca8e4c08a78 tries to remove the error produced with m4_pattern_allow, but that just silences the sanity check. Instead, replace m4_esyscmd_s with m4_esyscmd + manual removal of newlines. --- configure.ac | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index d7fa14829..6a42e6007 100644 --- a/configure.ac +++ b/configure.ac @@ -8,12 +8,10 @@ # configure the build process. # -m4_pattern_allow(m4_esyscmd_s) - m4_syscmd([build_tools/git_version_gen.sh 2>/dev/null]) AC_INIT(fish, - m4_esyscmd_s([cut -f 3 -d ' ' FISH-BUILD-VERSION-FILE]), + m4_esyscmd([cut -f 3 -d ' ' FISH-BUILD-VERSION-FILE | tr -d '\n']), fish-users@lists.sf.net) conf_arg=$@ From 588c520c4a4538d1c3fc6a875441aadf05ab8112 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 17 Aug 2013 15:46:33 -0700 Subject: [PATCH 064/170] Move FISH_BUILD_VERSION from osx/config.h to the pbxproj so that we can build with the generated config.h --- fish.xcodeproj/project.pbxproj | 3 +++ osx/config.h | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/fish.xcodeproj/project.pbxproj b/fish.xcodeproj/project.pbxproj index f4e7160a3..d1b78d8df 100644 --- a/fish.xcodeproj/project.pbxproj +++ b/fish.xcodeproj/project.pbxproj @@ -1190,6 +1190,7 @@ "DATADIR=L\\\"/usr/local/share\\\"", "SYSCONFDIR=L\\\"/usr/local/etc\\\"", "BINDIR=L\\\"/usr/local/bin\\\"", + "FISH_BUILD_VERSION=\\\"2.0.0\\\"", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; @@ -1341,6 +1342,7 @@ "DATADIR=L\\\"/usr/local/share\\\"", "SYSCONFDIR=L\\\"/usr/local/etc\\\"", "BINDIR=L\\\"/usr/local/bin\\\"", + "FISH_BUILD_VERSION=\\\"2.0.0\\\"", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -1368,6 +1370,7 @@ "DATADIR=L\\\"/usr/local/share\\\"", "SYSCONFDIR=L\\\"/usr/local/etc\\\"", "BINDIR=L\\\"/usr/local/bin\\\"", + "FISH_BUILD_VERSION=\\\"2.0.0\\\"", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; diff --git a/osx/config.h b/osx/config.h index 417dec68b..9872a2e12 100644 --- a/osx/config.h +++ b/osx/config.h @@ -193,7 +193,6 @@ /* Define to the version of this package. */ #define PACKAGE_VERSION "2.0.0" -#define FISH_BUILD_VERSION PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 From 77b13d02f0913237aa1cb791d334d4608f31e70d Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 17 Aug 2013 17:00:15 -0700 Subject: [PATCH 065/170] Fix "." function to not shadow scopes, so the tests pass again. Remove eval's use of "." function. --- share/functions/eval.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/functions/eval.fish b/share/functions/eval.fish index 432364ea5..52dee178d 100644 --- a/share/functions/eval.fish +++ b/share/functions/eval.fish @@ -20,7 +20,7 @@ function eval -S -d "Evaluate parameters as a command" status --job-control full end - echo "begin; $argv ;end eval2_inner <&3 3<&-" | . 3<&0 + echo "begin; $argv ;end eval2_inner <&3 3<&-" | source 3<&0 set -l res $status status --job-control $mode From 88efc737975efcc772fdecfd70191c1c0273c55b Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 17 Aug 2013 17:04:16 -0700 Subject: [PATCH 066/170] Actually commit the no-scope-shadowing to . function --- share/config.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/config.fish b/share/config.fish index e0b07bf9e..2c1f8b526 100644 --- a/share/config.fish +++ b/share/config.fish @@ -110,7 +110,7 @@ function __fish_on_interactive --on-event fish_prompt end # "." command for compatibility with old fish versions. -function . --description 'Evaluate contents of file (deprecated, see "source")' +function . --description 'Evaluate contents of file (deprecated, see "source")' --no-scope-shadowing if begin test (count $argv) -eq 0 # Uses tty directly, as isatty depends on "." From 2979d3bf169f51fb2ba218897994745754f830f9 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sun, 18 Aug 2013 10:57:33 +0200 Subject: [PATCH 067/170] Fix #684 by putting newline after $argv It's rather hacky, but it sort of works. (but then, this makes fish compare to PHP (but PHP doesn't put that newline), so perhaps I shouldn't do that - http://git.io/GFurbg) --- share/functions/eval.fish | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/share/functions/eval.fish b/share/functions/eval.fish index 52dee178d..19f20731b 100644 --- a/share/functions/eval.fish +++ b/share/functions/eval.fish @@ -1,4 +1,3 @@ - function eval -S -d "Evaluate parameters as a command" # If we are in an interactive shell, eval should enable full @@ -20,7 +19,7 @@ function eval -S -d "Evaluate parameters as a command" status --job-control full end - echo "begin; $argv ;end eval2_inner <&3 3<&-" | source 3<&0 + echo "begin; $argv "\n" ;end eval2_inner <&3 3<&-" | source 3<&0 set -l res $status status --job-control $mode From e849beabbab31c83ac57693cb0a7ac1e58f8cfd5 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 18 Aug 2013 16:55:01 -0700 Subject: [PATCH 068/170] Initial work towards various IO cleanups with an eye to fixing https://github.com/fish-shell/fish-shell/issues/110 --- exec.cpp | 30 ++++++++++++++++++------------ io.cpp | 6 ++++++ io.h | 1 + parser.cpp | 5 ++--- postfork.cpp | 26 +++++++++++++++++--------- proc.cpp | 10 +++++----- proc.h | 12 +++++++++--- share/functions/eval.fish | 13 +++++++++++++ tests/test1.in | 5 +++++ tests/test1.out | 5 +++++ 10 files changed, 81 insertions(+), 32 deletions(-) diff --git a/exec.cpp b/exec.cpp index d5c7d4bf8..c8c58c9cf 100644 --- a/exec.cpp +++ b/exec.cpp @@ -49,7 +49,6 @@ #include "expand.h" #include "signal.h" - #include "parse_util.h" /** @@ -490,7 +489,7 @@ static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t &out_chain, s static void internal_exec_helper(parser_t &parser, const wchar_t *def, enum block_type_t block_type, - io_chain_t &ios) + const io_chain_t &ios) { io_chain_t morphed_chain; std::vector opened_fds; @@ -540,9 +539,10 @@ static bool can_use_posix_spawn_for_job(const job_t *job, const process_t *proce /* Now see if we have a redirection involving a file. The only one we allow is /dev/null, which we assume will not fail. */ bool result = true; - for (size_t idx = 0; idx < job->io.size(); idx++) + const io_chain_t &ios = job->io_chain(); + for (size_t idx = 0; idx < ios.size(); idx++) { - const shared_ptr &io = job->io.at(idx); + const shared_ptr &io = ios.at(idx); if (redirection_is_to_real_file(io.get())) { result = false; @@ -621,9 +621,10 @@ void exec(parser_t &parser, job_t *j) } const io_buffer_t *input_redirect = NULL; - for (size_t idx = 0; idx < j->io.size(); idx++) + const io_chain_t &ios = j->io_chain(); + for (size_t idx = 0; idx < ios.size(); idx++) { - const shared_ptr &io = j->io.at(idx); + const shared_ptr &io = ios.at(idx); if ((io->io_mode == IO_BUFFER)) { @@ -770,13 +771,14 @@ void exec(parser_t &parser, job_t *j) pipe_read.reset(new io_pipe_t(p->pipe_read_fd, true)); /* Record the current read in pipe_read */ pipe_read->pipe_fd[0] = pipe_current_read; - j->io.push_back(pipe_read); + j->append_io(pipe_read); } if (p->next) { pipe_write.reset(new io_pipe_t(p->pipe_write_fd, false)); - j->io.push_back(pipe_write); + j->append_io(pipe_write); + } /* @@ -821,6 +823,10 @@ void exec(parser_t &parser, job_t *j) pipe_next_read = local_pipe[0]; } + //fprintf(stderr, "before IO: "); + //io_print(j->io); + + switch (p->type) { case INTERNAL_FUNCTION: @@ -873,13 +879,13 @@ void exec(parser_t &parser, job_t *j) } else { - j->io.push_back(io_buffer); + j->append_io(io_buffer); } } if (! exec_error) { - internal_exec_helper(parser, def.c_str(), TOP, j->io); + internal_exec_helper(parser, def.c_str(), TOP, j->io_chain()); } parser.allow_function(); @@ -915,7 +921,7 @@ void exec(parser_t &parser, job_t *j) case INTERNAL_BUILTIN: { int builtin_stdin=0; - int close_stdin=0; + bool close_stdin = false; /* If this is the first process, check the io @@ -959,7 +965,7 @@ void exec(parser_t &parser, job_t *j) } else { - close_stdin = 1; + close_stdin = true; } break; diff --git a/io.cpp b/io.cpp index da1ebb0cd..2882a59ae 100644 --- a/io.cpp +++ b/io.cpp @@ -202,6 +202,12 @@ void io_chain_t::push_back(const shared_ptr &element) std::vector >::push_back(element); } +void io_chain_t::push_front(const shared_ptr &element) +{ + assert(element.get() != NULL); + this->insert(this->begin(), element); +} + void io_remove(io_chain_t &list, const shared_ptr &element) { list.remove(element); diff --git a/io.h b/io.h index 6a98f380d..a5f74a1af 100644 --- a/io.h +++ b/io.h @@ -188,6 +188,7 @@ public: void remove(const shared_ptr &element); void push_back(const shared_ptr &element); + void push_front(const shared_ptr &element); shared_ptr get_io_for_fd(int fd) const; shared_ptr get_io_for_fd(int fd); diff --git a/parser.cpp b/parser.cpp index d6aa18868..af5e1107a 100644 --- a/parser.cpp +++ b/parser.cpp @@ -1559,7 +1559,7 @@ void parser_t::parse_job_argument_list(process_t *p, if (new_io.get() != NULL) { - j->io.push_back(new_io); + j->append_io(new_io); } } @@ -2318,7 +2318,6 @@ static bool job_should_skip_elseif(const job_t *job, const block_t *current_bloc void parser_t::eval_job(tokenizer_t *tok) { ASSERT_IS_MAIN_THREAD(); - job_t *j; int start_pos = job_start_pos = tok_get_pos(tok); long long t1=0, t2=0, t3=0; @@ -2341,7 +2340,7 @@ void parser_t::eval_job(tokenizer_t *tok) { case TOK_STRING: { - j = this->job_create(); + job_t *j = this->job_create(); job_set_flag(j, JOB_FOREGROUND, 1); job_set_flag(j, JOB_TERMINAL, job_get_flag(j, JOB_CONTROL)); job_set_flag(j, JOB_TERMINAL, job_get_flag(j, JOB_CONTROL) \ diff --git a/postfork.cpp b/postfork.cpp index 6553104b3..82d15e17c 100644 --- a/postfork.cpp +++ b/postfork.cpp @@ -37,6 +37,8 @@ /** pipe error */ #define LOCAL_PIPE_ERROR "An error occurred while setting up pipe" +static bool log_redirections = false; + /* Cover for debug_safe that can take an int. The format string should expect a %s */ static void debug_safe_int(int level, const char *format, int val) { @@ -164,11 +166,11 @@ static void free_redirected_fds_from_pipes(io_chain_t &io_chain) \return 0 on sucess, -1 on failiure */ -static int handle_child_io(io_chain_t &io_chain) +static int handle_child_io(const io_chain_t &io_chain) { - + //fprintf(stderr, "child IO for %d\n", getpid()); close_unused_internal_pipes(io_chain); - free_redirected_fds_from_pipes(io_chain); + //free_redirected_fds_from_pipes(io_chain); for (size_t idx = 0; idx < io_chain.size(); idx++) { io_data_t *io = io_chain.at(idx).get(); @@ -183,6 +185,7 @@ static int handle_child_io(io_chain_t &io_chain) { case IO_CLOSE: { + if (log_redirections) fprintf(stderr, "%d: close %d\n", getpid(), io->fd); if (close(io->fd)) { debug_safe_int(0, "Failed to close file descriptor %s", io->fd); @@ -232,13 +235,17 @@ static int handle_child_io(io_chain_t &io_chain) case IO_FD: { + int old_fd = static_cast(io)->old_fd; + if (log_redirections) fprintf(stderr, "%d: fd dup %d to %d\n", getpid(), old_fd, io->fd); + /* This call will sometimes fail, but that is ok, this is just a precausion. */ close(io->fd); - if (dup2(static_cast(io)->old_fd, io->fd) == -1) + + if (dup2(old_fd, io->fd) == -1) { debug_safe_int(1, FD_ERROR, io->fd); safe_perror("dup2"); @@ -262,6 +269,7 @@ static int handle_child_io(io_chain_t &io_chain) io->pipe_fd[0], io->pipe_fd[1]); */ + if (log_redirections) fprintf(stderr, "%d: %s dup %d to %d\n", getpid(), io->io_mode == IO_BUFFER ? "buffer" : "pipe", io_pipe->pipe_fd[write_pipe_idx], io->fd); if (dup2(io_pipe->pipe_fd[write_pipe_idx], io->fd) != io->fd) { debug_safe(1, LOCAL_PIPE_ERROR); @@ -295,7 +303,7 @@ int setup_child_process(job_t *j, process_t *p) if (ok) { - ok = (0 == handle_child_io(j->io)); + ok = (0 == handle_child_io(j->io_chain())); if (p != 0 && ! ok) { exit_without_destructors(1); @@ -436,19 +444,19 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_fil err = posix_spawnattr_setsigmask(attr, &sigmask); /* Make sure that our pipes don't use an fd that the redirection itself wants to use */ - free_redirected_fds_from_pipes(j->io); + //free_redirected_fds_from_pipes(j->io); /* Close unused internal pipes */ std::vector files_to_close; - get_unused_internal_pipes(files_to_close, j->io); + get_unused_internal_pipes(files_to_close, j->io_chain()); for (size_t i = 0; ! err && i < files_to_close.size(); i++) { err = posix_spawn_file_actions_addclose(actions, files_to_close.at(i)); } - for (size_t idx = 0; idx < j->io.size(); idx++) + for (size_t idx = 0; idx < j->io_chain().size(); idx++) { - shared_ptr io = j->io.at(idx); + shared_ptr io = j->io_chain().at(idx); if (io->io_mode == IO_FD) { diff --git a/proc.cpp b/proc.cpp index d0412414b..d5dae9298 100644 --- a/proc.cpp +++ b/proc.cpp @@ -542,11 +542,11 @@ process_t::~process_t() job_t::job_t(job_id_t jobid) : command_str(), command_narrow(), + io(), first_process(NULL), pgid(0), tmodes(), job_id(jobid), - io(), flags(0) { } @@ -876,9 +876,9 @@ static int select_try(job_t *j) FD_ZERO(&fds); - for (size_t idx = 0; idx < j->io.size(); idx++) + for (size_t idx = 0; idx < j->io_chain().size(); idx++) { - const io_data_t *io = j->io.at(idx).get(); + const io_data_t *io = j->io_chain().at(idx).get(); if (io->io_mode == IO_BUFFER) { CAST_INIT(const io_pipe_t *, io_pipe, io); @@ -917,9 +917,9 @@ static void read_try(job_t *j) /* Find the last buffer, which is the one we want to read from */ - for (size_t idx = 0; idx < j->io.size(); idx++) + for (size_t idx = 0; idx < j->io_chain().size(); idx++) { - io_data_t *d = j->io.at(idx).get(); + io_data_t *d = j->io_chain().at(idx).get(); if (d->io_mode == IO_BUFFER) { buff = static_cast(d); diff --git a/proc.h b/proc.h index 163831116..7a0dc3a11 100644 --- a/proc.h +++ b/proc.h @@ -272,6 +272,7 @@ void release_job_id(job_id_t jobid); A struct represeting a job. A job is basically a pipeline of one or more processes and a couple of flags. */ +class parser_t; class job_t { /** @@ -284,6 +285,10 @@ class job_t /* narrow copy so we don't have to convert after fork */ narrow_string_rep_t command_narrow; + /** List of all IO redirections for this job. */ + io_chain_t io; + friend void exec(parser_t &parser, job_t *j); + /* No copying */ job_t(const job_t &rhs); void operator=(const job_t &); @@ -350,13 +355,14 @@ public: */ const job_id_t job_id; - /** List of all IO redirections for this job. */ - io_chain_t io; - /** Bitset containing information about the job. A combination of the JOB_* constants. */ unsigned int flags; + + const io_chain_t &io_chain() const { return this->io; } + + void append_io(const shared_ptr & new_io) { this->io.push_back(new_io); } }; /** diff --git a/share/functions/eval.fish b/share/functions/eval.fish index 19f20731b..939b17c9e 100644 --- a/share/functions/eval.fish +++ b/share/functions/eval.fish @@ -19,6 +19,19 @@ function eval -S -d "Evaluate parameters as a command" status --job-control full end + # rfish: To eval 'foo', we construct a block "begin ; foo; end <&3 3<&-" + # The 'eval2_inner' is a param to 'begin' itself; I believe it does nothing. + # Note the redirections are also within the quotes. + # + # We then pipe this to 'source 3<&0' which dup2's 3 to stdin. + # + # You might expect that the dup2(3, stdin) should overwrite stdin, + # and therefore prevent 'source' from reading the piped-in block. This doesn't happen + # because when you pipe to a builtin, we don't overwrite stdin with the read end + # of the block; instead we set a separate fd in a variable 'builtin_stdin', which is + # what it reads from. So builtins are magic in that, in pipes, their stdin + # is not fd 0. + echo "begin; $argv "\n" ;end eval2_inner <&3 3<&-" | source 3<&0 set -l res $status diff --git a/tests/test1.in b/tests/test1.in index 4c261e10c..c180159c8 100644 --- a/tests/test1.in +++ b/tests/test1.in @@ -94,6 +94,11 @@ else end echo Test 5 $sta +# Verify that we can turn stderr into stdout and then pipe it. +# Note that the order here seems unspecified - 'errput' appears before 'output', why? +echo Test redirections +begin ; echo output ; echo errput 1>&2 ; end 2>&1 | tee /tmp/tee_test.txt ; cat /tmp/tee_test.txt + # echo tests echo 'abc\ndef' diff --git a/tests/test1.out b/tests/test1.out index 13219ff33..c6ecbb308 100644 --- a/tests/test1.out +++ b/tests/test1.out @@ -18,6 +18,11 @@ Test pass Test 3 pass Test 4 pass Test 5 pass +Test redirections +errput +output +errput +output abc\ndef abc def From fb89e1a26fabdb47fcf8a791b1fbd8418f3ce60f Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 18 Aug 2013 17:05:43 -0700 Subject: [PATCH 069/170] Reenable free_redirected_fds_from_pipes. --- postfork.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/postfork.cpp b/postfork.cpp index 82d15e17c..2a00581b1 100644 --- a/postfork.cpp +++ b/postfork.cpp @@ -107,8 +107,8 @@ int set_child_group(job_t *j, process_t *p, int print_errors) return res; } -/** Make sure the fd used by each redirection is not used by a pipe. */ -static void free_redirected_fds_from_pipes(io_chain_t &io_chain) +/** Make sure the fd used by each redirection is not used by a pipe. Note that while this does not modify the vector, it does modify the IO redirections within (gulp) */ +static void free_redirected_fds_from_pipes(const io_chain_t &io_chain) { size_t max = io_chain.size(); for (size_t i = 0; i < max; i++) @@ -170,7 +170,7 @@ static int handle_child_io(const io_chain_t &io_chain) { //fprintf(stderr, "child IO for %d\n", getpid()); close_unused_internal_pipes(io_chain); - //free_redirected_fds_from_pipes(io_chain); + free_redirected_fds_from_pipes(io_chain); for (size_t idx = 0; idx < io_chain.size(); idx++) { io_data_t *io = io_chain.at(idx).get(); @@ -444,7 +444,7 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_fil err = posix_spawnattr_setsigmask(attr, &sigmask); /* Make sure that our pipes don't use an fd that the redirection itself wants to use */ - //free_redirected_fds_from_pipes(j->io); + free_redirected_fds_from_pipes(j->io_chain()); /* Close unused internal pipes */ std::vector files_to_close; From f4f2847662a57c99a3ef0ae76adb304deccc5cac Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 18 Aug 2013 17:06:20 -0700 Subject: [PATCH 070/170] Trivial cleanup of a function in proc.cpp --- proc.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/proc.cpp b/proc.cpp index d5dae9298..b8231c389 100644 --- a/proc.cpp +++ b/proc.cpp @@ -339,9 +339,7 @@ int job_signal(job_t *j, int signal) } else { - process_t *p; - - for (p = j->first_process; p; p=p->next) + for (process_t *p = j->first_process; p; p=p->next) { if (! p->completed) { From 4899086b3c57ff2c36e62458ebb2986b95c2f631 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 19 Aug 2013 16:16:41 -0700 Subject: [PATCH 071/170] Big fat refactoring of how redirections work. In fish 1.x and 2.0.0, the redirections for a process were flattened into a big list associated with the job, so there was no way to tell which redirections applied to each process. Each process therefore got all the redirections associated with the job. See https://github.com/fish-shell/fish-shell/issues/877 for how this could manifest. With this change, jobs only track their block-level redirections. Process level redirections are correctly associated with the process, and at exec time we stitch them together (block, pipe, and process redirects). This fixes the weird issues where redirects bleed across pipelines (like #877), and also allows us to play with the order in which redirections are applied, since the final list is constructed right before it's needed. This lets us put pipes after block level redirections but before process level redirections, so that a 2>&1-type redirection gets picked up after the pipe, i.e. it should fix https://github.com/fish-shell/fish-shell/issues/110 This is a significant change. The tests all pass. Cross your fingers. --- exec.cpp | 166 ++++++++++++++++++++++++++++++--------------------- exec.h | 2 +- io.cpp | 7 ++- io.h | 1 + parser.cpp | 21 ++++--- parser.h | 6 +- postfork.cpp | 14 ++--- postfork.h | 6 +- proc.cpp | 25 ++++++-- proc.h | 26 ++++++-- reader.cpp | 24 ++++---- 11 files changed, 182 insertions(+), 116 deletions(-) diff --git a/exec.cpp b/exec.cpp index c8c58c9cf..9e70d2cc2 100644 --- a/exec.cpp +++ b/exec.cpp @@ -167,6 +167,21 @@ static bool redirection_is_to_real_file(const io_data_t *io) return result; } +static bool chain_contains_redirection_to_real_file(const io_chain_t &io_chain) +{ + bool result = false; + for (size_t idx=0; idx < io_chain.size(); idx++) + { + const shared_ptr &io = io_chain.at(idx); + if (redirection_is_to_real_file(io.get())) + { + result = true; + break; + } + } + return result; +} + void print_open_fds(void) { for (size_t i=0; i < open_fds.size(); ++i) @@ -539,15 +554,9 @@ static bool can_use_posix_spawn_for_job(const job_t *job, const process_t *proce /* Now see if we have a redirection involving a file. The only one we allow is /dev/null, which we assume will not fail. */ bool result = true; - const io_chain_t &ios = job->io_chain(); - for (size_t idx = 0; idx < ios.size(); idx++) + if (chain_contains_redirection_to_real_file(job->block_io_chain()) || chain_contains_redirection_to_real_file(process->io_chain())) { - const shared_ptr &io = ios.at(idx); - if (redirection_is_to_real_file(io.get())) - { - result = false; - break; - } + result = false; } return result; } @@ -584,13 +593,11 @@ static void exec_no_exec(parser_t &parser, const job_t *job) } } -void exec(parser_t &parser, job_t *j) +void exec_job(parser_t &parser, job_t *j) { pid_t pid = 0; sigset_t chldset; - shared_ptr io_buffer; - /* Set to true if something goes wrong while exec:ing the job, in which case the cleanup code will kick in. @@ -615,34 +622,35 @@ void exec(parser_t &parser, job_t *j) debug(4, L"Exec job '%ls' with id %d", j->command_wcstr(), j->job_id); - if (! parser.block_io.empty()) - { - j->io.insert(j->io.begin(), parser.block_io.begin(), parser.block_io.end()); - } + /* PCA Here we detect the special case of an input buffer redirection, i.e. we want a process to receive data that we hold in a buffer (it is an INPUT for the process, but an output for fish). This is extremely rare: I believe only run_pager creates these and it would be nice to dump it. So we can only have at most one. - const io_buffer_t *input_redirect = NULL; - const io_chain_t &ios = j->io_chain(); - for (size_t idx = 0; idx < ios.size(); idx++) + It would be great to wean fish_pager off of input redirections so that we can dump input redirections and the INTERNAL_BUFFER process type altogether. + */ + const io_buffer_t *single_magic_input_redirect = NULL; + const io_chain_t all_ios = j->all_io_redirections(); + for (size_t idx = 0; idx < all_ios.size(); idx++) { - const shared_ptr &io = ios.at(idx); + const shared_ptr &io = all_ios.at(idx); if ((io->io_mode == IO_BUFFER)) { CAST_INIT(io_buffer_t *, io_buffer, io.get()); if (io_buffer->is_input) { + /* We expect to have at most one of these, per the comment above. Note that this assertion is the only reason we don't break out of the loop below */ + assert(single_magic_input_redirect == NULL && "Should have at most one input IO_BUFFER"); + /* Input redirection - create a new gobetween process to take care of buffering, save the redirection in input_redirect */ process_t *fake = new process_t(); fake->type = INTERNAL_BUFFER; - fake->pipe_write_fd = 1; + fake->pipe_write_fd = STDOUT_FILENO; j->first_process->pipe_read_fd = io->fd; fake->next = j->first_process; j->first_process = fake; - input_redirect = io_buffer; - break; + single_magic_input_redirect = io_buffer; } } } @@ -658,7 +666,9 @@ void exec(parser_t &parser, job_t *j) setup_child_process makes sure signals are properly set up. It will also call signal_unblock */ - if (!setup_child_process(j, 0)) + + /* PCA This is for handling exec. Passing all_ios here matches what fish 2.0.0 and 1.x did. It's known to be wrong - for example, it means that redirections bound for subsequent commands in the pipeline will apply to exec. However, using exec in a pipeline doesn't really make sense, so I'm not trying to fix it here. */ + if (!setup_child_process(j, 0, all_ios)) { /* launch_process _never_ returns @@ -752,6 +762,9 @@ void exec(parser_t &parser, job_t *j) int pipe_current_read = -1, pipe_current_write = -1, pipe_next_read = -1; for (process_t *p=j->first_process; p; p = p->next) { + /* The IO chain for this process. It starts with the block IO, then pipes, and then gets any from the process */ + io_chain_t process_net_io_chain = j->block_io_chain(); + /* "Consume" any pipe_next_read by making it current */ assert(pipe_current_read == -1); pipe_current_read = pipe_next_read; @@ -762,7 +775,23 @@ void exec(parser_t &parser, job_t *j) /* The pipes the current process write to and read from. Unfortunately these can't be just allocated on the stack, since - j->io wants shared_ptr. */ + j->io wants shared_ptr. + + The write pipe (destined for stdout) needs to occur before redirections. For example, with a redirection like this: + `foo 2>&1 | bar`, what we want to happen is this: + + dup2(pipe, stdout) + dup2(stdout, stderr) + + so that stdout and stderr both wind up referencing the pipe. + + The read pipe (destined for stdin) is more ambiguous. Imagine a pipeline like this: + + echo alpha | cat < beta.txt + + Should cat output alpha or beta? bash and ksh output 'beta', tcsh gets it right and complains about ambiguity, and zsh outputs both (!). No shells appear to output 'alpha', so we match bash here. That means putting the pipe first, so that it gets trumped by the file redirection. + */ + shared_ptr pipe_write; shared_ptr pipe_read; @@ -771,16 +800,19 @@ void exec(parser_t &parser, job_t *j) pipe_read.reset(new io_pipe_t(p->pipe_read_fd, true)); /* Record the current read in pipe_read */ pipe_read->pipe_fd[0] = pipe_current_read; - j->append_io(pipe_read); + process_net_io_chain.push_back(pipe_read); } if (p->next) { pipe_write.reset(new io_pipe_t(p->pipe_write_fd, false)); - j->append_io(pipe_write); + process_net_io_chain.push_back(pipe_write); } + /* Now that we've added our pipes, add the rest of the IO redirections associated with that process */ + process_net_io_chain.append(p->io_chain()); + /* This call is used so the global environment variable array is regenerated, if needed, before the fork. That way, we @@ -826,14 +858,12 @@ void exec(parser_t &parser, job_t *j) //fprintf(stderr, "before IO: "); //io_print(j->io); - + // This is the IO buffer we use for storing the output of a block or function when it is in a pipeline + shared_ptr block_output_io_buffer; switch (p->type) { case INTERNAL_FUNCTION: { - int shadows; - - /* Calls to function_get_definition might need to source a file as a part of autoloading, hence there @@ -845,7 +875,7 @@ void exec(parser_t &parser, job_t *j) bool function_exists = function_get_definition(p->argv0(), &def); wcstring_list_t named_arguments = function_get_named_arguments(p->argv0()); - shadows = function_get_shadows(p->argv0()); + bool shadows = function_get_shadows(p->argv0()); signal_block(); @@ -871,21 +901,22 @@ void exec(parser_t &parser, job_t *j) if (p->next) { // Be careful to handle failure, e.g. too many open fds - io_buffer.reset(io_buffer_t::create(0)); - if (io_buffer.get() == NULL) + block_output_io_buffer.reset(io_buffer_t::create(false /* = not input */, STDOUT_FILENO)); + if (block_output_io_buffer.get() == NULL) { exec_error = true; job_mark_process_as_failed(j, p); } else { - j->append_io(io_buffer); + #warning is this bad because we need to be able to read this from select_try? + process_net_io_chain.push_back(block_output_io_buffer); } } if (! exec_error) { - internal_exec_helper(parser, def.c_str(), TOP, j->io_chain()); + internal_exec_helper(parser, def.c_str(), TOP, process_net_io_chain); } parser.allow_function(); @@ -898,21 +929,22 @@ void exec(parser_t &parser, job_t *j) { if (p->next) { - io_buffer.reset(io_buffer_t::create(0)); - if (io_buffer.get() == NULL) + #warning is this bad because we need to be able to read this from select_try? + block_output_io_buffer.reset(io_buffer_t::create(0)); + if (block_output_io_buffer.get() == NULL) { exec_error = true; job_mark_process_as_failed(j, p); } else { - j->io.push_back(io_buffer); + process_net_io_chain.push_back(block_output_io_buffer); } } if (! exec_error) { - internal_exec_helper(parser, p->argv0(), TOP, j->io); + internal_exec_helper(parser, p->argv0(), TOP, process_net_io_chain); } break; @@ -930,7 +962,7 @@ void exec(parser_t &parser, job_t *j) */ if (p == j->first_process) { - const shared_ptr in = io_chain_get(j->io, 0); + const shared_ptr in = process_net_io_chain.get_io_for_fd(STDIN_FILENO); if (in) { @@ -1029,15 +1061,15 @@ void exec(parser_t &parser, job_t *j) builtin_push_io(parser, builtin_stdin); - builtin_out_redirect = has_fd(j->io, 1); - builtin_err_redirect = has_fd(j->io, 2); + builtin_out_redirect = has_fd(process_net_io_chain, STDOUT_FILENO); + builtin_err_redirect = has_fd(process_net_io_chain, STDERR_FILENO); const int fg = job_get_flag(j, JOB_FOREGROUND); job_set_flag(j, JOB_FOREGROUND, 0); signal_unblock(); - p->status = builtin_run(parser, p->get_argv(), j->io); + p->status = builtin_run(parser, p->get_argv(), process_net_io_chain); builtin_out_redirect=old_out; builtin_err_redirect=old_err; @@ -1083,7 +1115,7 @@ void exec(parser_t &parser, job_t *j) to buffer such io, since otherwise the internal pipe buffer might overflow. */ - if (!io_buffer) + if (! block_output_io_buffer.get()) { /* No buffer, so we exit directly. This means we @@ -1097,14 +1129,16 @@ void exec(parser_t &parser, job_t *j) break; } - io_remove(j->io, io_buffer); + // Here we must have a non-NULL block_output_io_buffer + assert(block_output_io_buffer.get() != NULL); + io_remove(process_net_io_chain, block_output_io_buffer); - io_buffer->read(); + block_output_io_buffer->read(); - const char *buffer = io_buffer->out_buffer_ptr(); - size_t count = io_buffer->out_buffer_size(); + const char *buffer = block_output_io_buffer->out_buffer_ptr(); + size_t count = block_output_io_buffer->out_buffer_size(); - if (io_buffer->out_buffer_size() > 0) + if (block_output_io_buffer->out_buffer_size() > 0) { /* We don't have to drain threads here because our child process is simple */ if (g_log_forks) @@ -1119,9 +1153,9 @@ void exec(parser_t &parser, job_t *j) This is the child process. Write out the contents of the pipeline. */ p->pid = getpid(); - setup_child_process(j, p); + setup_child_process(j, p, process_net_io_chain); - exec_write_and_exit(io_buffer->fd, buffer, count, status); + exec_write_and_exit(block_output_io_buffer->fd, buffer, count, status); } else { @@ -1145,7 +1179,7 @@ void exec(parser_t &parser, job_t *j) p->completed = 1; } - io_buffer.reset(); + block_output_io_buffer.reset(); break; } @@ -1153,9 +1187,9 @@ void exec(parser_t &parser, job_t *j) case INTERNAL_BUFFER: { - - const char *buffer = input_redirect->out_buffer_ptr(); - size_t count = input_redirect->out_buffer_size(); + assert(single_magic_input_redirect != NULL); + const char *buffer = single_magic_input_redirect->out_buffer_ptr(); + size_t count = single_magic_input_redirect->out_buffer_size(); /* We don't have to drain threads here because our child process is simple */ if (g_log_forks) @@ -1170,7 +1204,7 @@ void exec(parser_t &parser, job_t *j) contents of the pipeline. */ p->pid = getpid(); - setup_child_process(j, p); + setup_child_process(j, p, process_net_io_chain); exec_write_and_exit(1, buffer, count, 0); } @@ -1201,8 +1235,8 @@ void exec(parser_t &parser, job_t *j) bool fork_was_skipped = false; - const shared_ptr stdout_io = io_chain_get(j->io, STDOUT_FILENO); - const shared_ptr stderr_io = io_chain_get(j->io, STDERR_FILENO); + const shared_ptr stdout_io = process_net_io_chain.get_io_for_fd(STDOUT_FILENO); + const shared_ptr stderr_io = process_net_io_chain.get_io_for_fd(STDERR_FILENO); /* If we are outputting to a file, we have to actually do it, even if we have no output, so that we can truncate the file. Does not apply to /dev/null. */ bool must_fork = redirection_is_to_real_file(stdout_io.get()) || redirection_is_to_real_file(stderr_io.get()); @@ -1292,7 +1326,7 @@ void exec(parser_t &parser, job_t *j) if (g_log_forks) { printf("fork #%d: Executing fork for internal builtin for '%ls'\n", g_fork_count, p->argv0()); - io_print(j->io); + io_print(process_net_io_chain); } pid = execute_fork(false); if (pid == 0) @@ -1303,7 +1337,7 @@ void exec(parser_t &parser, job_t *j) then exit. */ p->pid = getpid(); - setup_child_process(j, p); + setup_child_process(j, p, process_net_io_chain); do_builtin_io(outbuff, outbuff_len, errbuff, errbuff_len); exit_without_destructors(p->status); } @@ -1346,7 +1380,7 @@ void exec(parser_t &parser, job_t *j) printf("fork #%d: forking for '%s' in '%ls:%ls'\n", g_fork_count, actual_cmd, file ? file : L"", func ? func : L"?"); fprintf(stderr, "IO chain for %s:\n", actual_cmd); - io_print(j->io); + io_print(process_net_io_chain); } #if FISH_USE_POSIX_SPAWN @@ -1357,7 +1391,7 @@ void exec(parser_t &parser, job_t *j) /* Create posix spawn attributes and actions */ posix_spawnattr_t attr = posix_spawnattr_t(); posix_spawn_file_actions_t actions = posix_spawn_file_actions_t(); - bool made_it = fork_actions_make_spawn_properties(&attr, &actions, j, p); + bool made_it = fork_actions_make_spawn_properties(&attr, &actions, j, p, process_net_io_chain); if (made_it) { /* We successfully made the attributes and actions; actually call posix_spawn */ @@ -1393,7 +1427,7 @@ void exec(parser_t &parser, job_t *j) { /* This is the child process. */ p->pid = getpid(); - setup_child_process(j, p); + setup_child_process(j, p, process_net_io_chain); safe_launch_process(p, actual_cmd, argv, envv); /* @@ -1441,12 +1475,6 @@ void exec(parser_t &parser, job_t *j) exec_close(pipe_current_write); pipe_current_write = -1; } - - if (pipe_write.get()) - j->io.remove(pipe_write); - - if (pipe_read.get()) - j->io.remove(pipe_read); } /* Clean up any file descriptors we left open */ diff --git a/exec.h b/exec.h index edae1e557..10eda29b6 100644 --- a/exec.h +++ b/exec.h @@ -42,7 +42,7 @@ */ class parser_t; -void exec(parser_t &parser, job_t *j); +void exec_job(parser_t &parser, job_t *j); /** Evaluate the expression cmd in a subshell, add the outputs into the diff --git a/io.cpp b/io.cpp index 2882a59ae..1ee36e72d 100644 --- a/io.cpp +++ b/io.cpp @@ -128,7 +128,7 @@ io_buffer_t *io_buffer_t::create(bool is_input, int fd) bool success = true; if (fd == -1) { - fd = is_input ? 0 : 1; + fd = is_input ? STDIN_FILENO : STDOUT_FILENO; } io_buffer_t *buffer_redirect = new io_buffer_t(fd, is_input); @@ -208,6 +208,11 @@ void io_chain_t::push_front(const shared_ptr &element) this->insert(this->begin(), element); } +void io_chain_t::append(const io_chain_t &chain) +{ + this->insert(this->end(), chain.begin(), chain.end()); +} + void io_remove(io_chain_t &list, const shared_ptr &element) { list.remove(element); diff --git a/io.h b/io.h index a5f74a1af..d4a0fadab 100644 --- a/io.h +++ b/io.h @@ -189,6 +189,7 @@ public: void remove(const shared_ptr &element); void push_back(const shared_ptr &element); void push_front(const shared_ptr &element); + void append(const io_chain_t &chain); shared_ptr get_io_for_fd(int fd) const; shared_ptr get_io_for_fd(int fd); diff --git a/parser.cpp b/parser.cpp index af5e1107a..c80d09cae 100644 --- a/parser.cpp +++ b/parser.cpp @@ -1168,9 +1168,9 @@ int parser_t::is_help(const wchar_t *s, int min_match) const (len >= (size_t)min_match && (wcsncmp(L"--help", s, len) == 0)); } -job_t *parser_t::job_create(void) +job_t *parser_t::job_create() { - job_t *res = new job_t(acquire_job_id()); + job_t *res = new job_t(acquire_job_id(), this->block_io); this->my_job_list.push_front(res); job_set_flag(res, @@ -1256,6 +1256,9 @@ void parser_t::parse_job_argument_list(process_t *p, wcstring unmatched; int unmatched_pos=0; + /* The set of IO redirections that we construct for the process */ + io_chain_t process_io_chain; + /* Test if this is the 'count' command. We need to special case count in the shell, since it should display a help message on @@ -1559,7 +1562,7 @@ void parser_t::parse_job_argument_list(process_t *p, if (new_io.get() != NULL) { - j->append_io(new_io); + process_io_chain.push_back(new_io); } } @@ -1613,7 +1616,9 @@ void parser_t::parse_job_argument_list(process_t *p, } } - return; + /* Store our IO chain. The existing chain should be empty. */ + assert(p->io_chain().empty()); + p->set_io_chain(process_io_chain); } /* @@ -2256,7 +2261,7 @@ void parser_t::skipped_exec(job_t * j) { if (!current_block->outer->skip) { - exec(*this, j); + exec_job(*this, j); return; } parser_t::pop_block(); @@ -2269,7 +2274,7 @@ void parser_t::skipped_exec(job_t * j) const if_block_t *ib = static_cast(current_block); if (ib->if_expr_evaluated && ! ib->any_branch_taken) { - exec(*this, j); + exec_job(*this, j); return; } } @@ -2278,7 +2283,7 @@ void parser_t::skipped_exec(job_t * j) { if (current_block->type() == SWITCH) { - exec(*this, j); + exec_job(*this, j); return; } } @@ -2415,7 +2420,7 @@ void parser_t::eval_job(tokenizer_t *tok) if (j->first_process->type==INTERNAL_BUILTIN && !j->first_process->next) was_builtin = 1; scoped_push tokenizer_pos_push(¤t_tokenizer_pos, job_begin_pos); - exec(*this, j); + exec_job(*this, j); /* Only external commands require a new fishd barrier */ if (!was_builtin) diff --git a/parser.h b/parser.h index c2ad6c9b7..fa49fcfb7 100644 --- a/parser.h +++ b/parser.h @@ -352,6 +352,9 @@ private: void print_errors(wcstring &target, const wchar_t *prefix); void print_errors_stderr(); + /** Create a job */ + job_t *job_create(); + public: std::vector profile_items; @@ -457,9 +460,6 @@ public: /** Return a description of the given blocktype */ const wchar_t *get_block_desc(int block) const; - /** Create a job */ - job_t *job_create(); - /** Removes a job */ bool job_remove(job_t *job); diff --git a/postfork.cpp b/postfork.cpp index 2a00581b1..713e2247c 100644 --- a/postfork.cpp +++ b/postfork.cpp @@ -292,7 +292,7 @@ static int handle_child_io(const io_chain_t &io_chain) } -int setup_child_process(job_t *j, process_t *p) +int setup_child_process(job_t *j, process_t *p, const io_chain_t &io_chain) { bool ok=true; @@ -303,7 +303,7 @@ int setup_child_process(job_t *j, process_t *p) if (ok) { - ok = (0 == handle_child_io(j->io_chain())); + ok = (0 == handle_child_io(io_chain)); if (p != 0 && ! ok) { exit_without_destructors(1); @@ -379,7 +379,7 @@ pid_t execute_fork(bool wait_for_threads_to_die) } #if FISH_USE_POSIX_SPAWN -bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_file_actions_t *actions, job_t *j, process_t *p) +bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_file_actions_t *actions, job_t *j, process_t *p, const io_chain_t &io_chain) { /* Initialize the output */ if (posix_spawnattr_init(attr) != 0) @@ -444,19 +444,19 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_fil err = posix_spawnattr_setsigmask(attr, &sigmask); /* Make sure that our pipes don't use an fd that the redirection itself wants to use */ - free_redirected_fds_from_pipes(j->io_chain()); + free_redirected_fds_from_pipes(io_chain); /* Close unused internal pipes */ std::vector files_to_close; - get_unused_internal_pipes(files_to_close, j->io_chain()); + get_unused_internal_pipes(files_to_close, io_chain); for (size_t i = 0; ! err && i < files_to_close.size(); i++) { err = posix_spawn_file_actions_addclose(actions, files_to_close.at(i)); } - for (size_t idx = 0; idx < j->io_chain().size(); idx++) + for (size_t idx = 0; idx < io_chain.size(); idx++) { - shared_ptr io = j->io_chain().at(idx); + const shared_ptr io = io_chain.at(idx); if (io->io_mode == IO_FD) { diff --git a/postfork.h b/postfork.h index ba82918a4..439cedff6 100644 --- a/postfork.h +++ b/postfork.h @@ -53,13 +53,13 @@ int set_child_group(job_t *j, process_t *p, int print_errors); \param j the job to set up the IO for \param p the child process to set up - \param io_chain the IO chain to use (ignores the job's iochain) + \param io_chain the IO chain to use \return 0 on sucess, -1 on failiure. When this function returns, signals are always unblocked. On failiure, signal handlers, io redirections and process group of the process is undefined. */ -int setup_child_process(job_t *j, process_t *p); +int setup_child_process(job_t *j, process_t *p, const io_chain_t &io_chain); /* Call fork(), optionally waiting until we are no longer multithreaded. If the forked child doesn't do anything that could allocate memory, take a lock, etc. (like call exec), then it's not necessary to wait for threads to die. If the forked child may do those things, it should wait for threads to die. */ @@ -73,7 +73,7 @@ void safe_report_exec_error(int err, const char *actual_cmd, const char * const #if FISH_USE_POSIX_SPAWN /* Initializes and fills in a posix_spawnattr_t; on success, the caller should destroy it via posix_spawnattr_destroy */ -bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_file_actions_t *actions, job_t *j, process_t *p); +bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_file_actions_t *actions, job_t *j, process_t *p, const io_chain_t &io_chain); #endif #endif diff --git a/proc.cpp b/proc.cpp index b8231c389..1ca700999 100644 --- a/proc.cpp +++ b/proc.cpp @@ -537,10 +537,10 @@ process_t::~process_t() delete this->next; } -job_t::job_t(job_id_t jobid) : +job_t::job_t(job_id_t jobid, const io_chain_t &bio) : command_str(), command_narrow(), - io(), + block_io(bio), first_process(NULL), pgid(0), tmodes(), @@ -556,6 +556,17 @@ job_t::~job_t() release_job_id(job_id); } +/* Return all the IO redirections. Start with the block IO, then walk over the processes */ +io_chain_t job_t::all_io_redirections() const +{ + io_chain_t result = this->block_io; + for (process_t *p = this->first_process; p != NULL; p = p->next) + { + result.append(p->io_chain()); + } + return result; +} + /* This is called from a signal handler */ void job_handle_signal(int signal, siginfo_t *info, void *con) { @@ -874,9 +885,10 @@ static int select_try(job_t *j) FD_ZERO(&fds); - for (size_t idx = 0; idx < j->io_chain().size(); idx++) + const io_chain_t chain = j->all_io_redirections(); + for (size_t idx = 0; idx < chain.size(); idx++) { - const io_data_t *io = j->io_chain().at(idx).get(); + const io_data_t *io = chain.at(idx).get(); if (io->io_mode == IO_BUFFER) { CAST_INIT(const io_pipe_t *, io_pipe, io); @@ -915,9 +927,10 @@ static void read_try(job_t *j) /* Find the last buffer, which is the one we want to read from */ - for (size_t idx = 0; idx < j->io_chain().size(); idx++) + const io_chain_t chain = j->all_io_redirections(); + for (size_t idx = 0; idx < chain.size(); idx++) { - io_data_t *d = j->io_chain().at(idx).get(); + io_data_t *d = chain.at(idx).get(); if (d->io_mode == IO_BUFFER) { buff = static_cast(d); diff --git a/proc.h b/proc.h index 7a0dc3a11..5e702a91a 100644 --- a/proc.h +++ b/proc.h @@ -134,6 +134,8 @@ private: /* narrow copy of argv0 so we don't have to convert after fork */ narrow_string_rep_t argv0_narrow; + io_chain_t process_io_chain; + /* No copying */ process_t(const process_t &rhs); void operator=(const process_t &rhs); @@ -190,6 +192,17 @@ public: return argv0_narrow.get(); } + /* IO chain getter and setter */ + const io_chain_t &io_chain() const + { + return process_io_chain; + } + + void set_io_chain(const io_chain_t &chain) + { + this->process_io_chain = chain; + } + /** actual command to pass to exec in case of EXTERNAL or INTERNAL_EXEC. */ wcstring actual_cmd; @@ -285,9 +298,8 @@ class job_t /* narrow copy so we don't have to convert after fork */ narrow_string_rep_t command_narrow; - /** List of all IO redirections for this job. */ - io_chain_t io; - friend void exec(parser_t &parser, job_t *j); + /* The IO chain associated with the block */ + const io_chain_t block_io; /* No copying */ job_t(const job_t &rhs); @@ -295,7 +307,7 @@ class job_t public: - job_t(job_id_t jobid); + job_t(job_id_t jobid, const io_chain_t &bio); ~job_t(); /** Returns whether the command is empty. */ @@ -360,9 +372,11 @@ public: */ unsigned int flags; - const io_chain_t &io_chain() const { return this->io; } + /* Returns the block IO redirections associated with the job. These are things like the IO redirections associated with the begin...end statement. */ + const io_chain_t &block_io_chain() const { return this->block_io; } - void append_io(const shared_ptr & new_io) { this->io.push_back(new_io); } + /* Fetch all the IO redirections associated with the job */ + io_chain_t all_io_redirections() const; }; /** diff --git a/reader.cpp b/reader.cpp index 0e5b45bd4..907a6aab2 100644 --- a/reader.cpp +++ b/reader.cpp @@ -1274,11 +1274,11 @@ static void run_pager(const wcstring &prefix, int is_quoted, const std::vector in(io_buffer_t::create(true, 3)); - shared_ptr out(io_buffer_t::create(false, 4)); + shared_ptr in_buff(io_buffer_t::create(true, 3)); + shared_ptr out_buff(io_buffer_t::create(false, 4)); // The above may fail e.g. if we have too many open fds - if (in.get() == NULL || out.get() == NULL) + if (in_buff.get() == NULL || out_buff.get() == NULL) return; wchar_t *escaped_separator; @@ -1350,26 +1350,26 @@ static void run_pager(const wcstring &prefix, int is_quoted, const std::vectorout_buffer_append(foo, strlen(foo)); + in_buff->out_buffer_append(foo, strlen(foo)); free(foo); term_donate(); parser_t &parser = parser_t::principal_parser(); io_chain_t io_chain; - io_chain.push_back(out); - io_chain.push_back(in); + io_chain.push_back(out_buff); + io_chain.push_back(in_buff); parser.eval(cmd, io_chain, TOP); term_steal(); - out->read(); + out_buff->read(); - int nil=0; - out->out_buffer_append((char *)&nil, 1); + const char zero = 0; + out_buff->out_buffer_append(&zero, 1); - const char *outbuff = out->out_buffer_ptr(); - if (outbuff) + const char *out_data = out_buff->out_buffer_ptr(); + if (out_data) { - const wcstring str = str2wcstring(outbuff); + const wcstring str = str2wcstring(out_data); size_t idx = str.size(); while (idx--) { From ee113a5632a407f5ccf6767152d50ea2aae57675 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 19 Aug 2013 18:17:01 -0700 Subject: [PATCH 072/170] Replace some #warnings with a comment explaining why the code is OK --- exec.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exec.cpp b/exec.cpp index 9e70d2cc2..85f73af62 100644 --- a/exec.cpp +++ b/exec.cpp @@ -909,7 +909,7 @@ void exec_job(parser_t &parser, job_t *j) } else { - #warning is this bad because we need to be able to read this from select_try? + /* This looks sketchy, because we're adding this io buffer locally - they aren't in the process or job redirection list. Therefore select_try won't be able to read them. However we call block_output_io_buffer->read() below, which reads until EOF. So there's no need to select on this. */ process_net_io_chain.push_back(block_output_io_buffer); } } @@ -929,7 +929,6 @@ void exec_job(parser_t &parser, job_t *j) { if (p->next) { - #warning is this bad because we need to be able to read this from select_try? block_output_io_buffer.reset(io_buffer_t::create(0)); if (block_output_io_buffer.get() == NULL) { @@ -938,6 +937,7 @@ void exec_job(parser_t &parser, job_t *j) } else { + /* See the comment above about it's OK to add an IO redirection to this local buffer, even though it won't be handled in select_try */ process_net_io_chain.push_back(block_output_io_buffer); } } From 69c6b007aa5d478873cedf0330f1a48641581467 Mon Sep 17 00:00:00 2001 From: lledey Date: Mon, 19 Aug 2013 22:14:20 -0400 Subject: [PATCH 073/170] Remove grep warning from make target completion grep was throwing warnings when no Makefile was found Signed-off-by: lledey --- share/functions/__fish_print_make_targets.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/functions/__fish_print_make_targets.fish b/share/functions/__fish_print_make_targets.fish index bda806f46..5be984b8c 100644 --- a/share/functions/__fish_print_make_targets.fish +++ b/share/functions/__fish_print_make_targets.fish @@ -3,6 +3,6 @@ function __fish_print_make_targets # Some seds (e.g. on Mac OS X), don't support \n in the RHS # Use a literal newline instead # http://sed.sourceforge.net/sedfaq4.html#s4.1 - sgrep -h -E '^[^#%=$[:space:]][^#%=$]*:([^=]|$)' $files | cut -d ":" -f 1 | sed -e 's/^ *//;s/ *$//;s/ */\\ + sgrep -h -E '^[^#%=$[:space:]][^#%=$]*:([^=]|$)' $files ^/dev/null | cut -d ":" -f 1 | sed -e 's/^ *//;s/ *$//;s/ */\\ /g' ^/dev/null end From d6791a836b887d8de79af6a2b2b2385d5ebc27b3 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Tue, 20 Aug 2013 20:08:56 -0700 Subject: [PATCH 074/170] Include the autosuggestion in history if it was truncated https://github.com/fish-shell/fish-shell/issues/650 --- reader.cpp | 4 ++-- screen.cpp | 6 +++++- screen.h | 5 ++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/reader.cpp b/reader.cpp index 907a6aab2..96d7bc44d 100644 --- a/reader.cpp +++ b/reader.cpp @@ -3517,9 +3517,9 @@ const wchar_t *reader_readline(void) data->search_buff.append(data->command_line); data->history_search = history_search_t(*data->history, data->search_buff, HISTORY_SEARCH_TYPE_CONTAINS); - /* Skip the autosuggestion as history */ + /* Skip the autosuggestion as history unless it was truncated */ const wcstring &suggest = data->autosuggestion; - if (! suggest.empty()) + if (! suggest.empty() && ! data->screen.autosuggestion_is_truncated) { data->history_search.skip_matches(wcstring_list_t(&suggest, 1 + &suggest)); } diff --git a/screen.cpp b/screen.cpp index 9cae7d360..8c8438346 100644 --- a/screen.cpp +++ b/screen.cpp @@ -1035,7 +1035,7 @@ struct screen_layout_t wcstring autosuggestion; /* Whether the prompts get their own line or not */ - bool prompts_get_own_line; + bool prompts_get_own_line; }; /* Given a vector whose indexes are offsets and whose values are the widths of the string if truncated at that offset, return the offset that fits in the given width. Returns width_by_offset.size() - 1 if they all fit. The first value in width_by_offset is assumed to be 0. */ @@ -1245,6 +1245,9 @@ void s_write(screen_t *s, /* Compute a layout */ const screen_layout_t layout = compute_layout(s, screen_width, left_prompt, right_prompt, explicit_command_line, autosuggestion, indent); + /* Determine whether, if we have an autosuggestion, it was truncated */ + s->autosuggestion_is_truncated = ! autosuggestion.empty() && autosuggestion != layout.autosuggestion; + /* Clear the desired screen */ s->desired.resize(0); s->desired.cursor.x = s->desired.cursor.y = 0; @@ -1402,6 +1405,7 @@ screen_t::screen_t() : last_right_prompt_width(), actual_width(SCREEN_WIDTH_UNINITIALIZED), soft_wrap_location(INVALID_LOCATION), + autosuggestion_is_truncated(false), need_clear_lines(false), need_clear_screen(false), actual_lines_before_reset(0), diff --git a/screen.h b/screen.h index 1dcb34bd7..0307fdd7d 100644 --- a/screen.h +++ b/screen.h @@ -140,6 +140,9 @@ public: /** If we support soft wrapping, we can output to this location without any cursor motion. */ screen_data_t::cursor_t soft_wrap_location; + + /** Whether the last-drawn autosuggestion (if any) is truncated, or hidden entirely */ + bool autosuggestion_is_truncated; /** This flag is set to true when there is reason to suspect that @@ -155,7 +158,7 @@ public: /** If we need to clear, this is how many lines the actual screen had, before we reset it. This is used when resizing the window larger: if the cursor jumps to the line above, we need to remember to clear the subsequent lines. */ size_t actual_lines_before_reset; - + /** These status buffers are used to check if any output has occurred other than from fish's main loop, in which case we need to redraw. From 7b6780f712abc45637bf0a049a6b7b2ec233172f Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Wed, 21 Aug 2013 13:46:11 -0700 Subject: [PATCH 075/170] Put read pipe last so that eval works again. Addresses https://github.com/fish-shell/fish-shell/issues/966 --- exec.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/exec.cpp b/exec.cpp index 85f73af62..dbfb66669 100644 --- a/exec.cpp +++ b/exec.cpp @@ -789,20 +789,19 @@ void exec_job(parser_t &parser, job_t *j) echo alpha | cat < beta.txt - Should cat output alpha or beta? bash and ksh output 'beta', tcsh gets it right and complains about ambiguity, and zsh outputs both (!). No shells appear to output 'alpha', so we match bash here. That means putting the pipe first, so that it gets trumped by the file redirection. + Should cat output alpha or beta? bash and ksh output 'beta', tcsh gets it right and complains about ambiguity, and zsh outputs both (!). No shells appear to output 'alpha', so we match bash here. That would mean putting the pipe first, so that it gets trumped by the file redirection. + + However, eval does this: + + echo "begin; $argv "\n" ;end eval2_inner <&3 3<&-" | source 3<&0 + + which depends on the redirection being evaluated before the pipe. So the write end of the pipe comes first, the read pipe of the pipe comes last. See issue #966. */ shared_ptr pipe_write; shared_ptr pipe_read; - if (p != j->first_process) - { - pipe_read.reset(new io_pipe_t(p->pipe_read_fd, true)); - /* Record the current read in pipe_read */ - pipe_read->pipe_fd[0] = pipe_current_read; - process_net_io_chain.push_back(pipe_read); - } - + /* Write pipe goes first */ if (p->next) { pipe_write.reset(new io_pipe_t(p->pipe_write_fd, false)); @@ -810,8 +809,18 @@ void exec_job(parser_t &parser, job_t *j) } - /* Now that we've added our pipes, add the rest of the IO redirections associated with that process */ + /* The explicit IO redirections associated with the process */ process_net_io_chain.append(p->io_chain()); + + /* Read pipe goes last */ + if (p != j->first_process) + { + pipe_read.reset(new io_pipe_t(p->pipe_read_fd, true)); + /* Record the current read in pipe_read */ + pipe_read->pipe_fd[0] = pipe_current_read; + process_net_io_chain.push_back(pipe_read); + } + /* This call is used so the global environment variable array From 7541fac245b47cce023ba4b12b4216e671508780 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Wed, 21 Aug 2013 14:41:12 -0700 Subject: [PATCH 076/170] Fix the build on OS X Mavericks https://github.com/fish-shell/fish-shell/issues/968 --- io.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/io.h b/io.h index d4a0fadab..17e2b3421 100644 --- a/io.h +++ b/io.h @@ -2,12 +2,16 @@ #define FISH_IO_H #include -#if __cplusplus > 199711L -// C++11 + +// Note that we have to include something to get any _LIBCPP_VERSION defined so we can detect libc++ +// So it's key that vector go above. If we didn't need vector for other reasons, we might include ciso646, which does nothing + +#if defined(_LIBCPP_VERSION) || __cplusplus > 199711L +// C++11 or libc++ (which is a C++11-only library, but the memory header works OK in C++03) #include using std::shared_ptr; #else -// C++03 +// C++03 or libstdc++ #include using std::tr1::shared_ptr; #endif From 05233aa6f4adea07b0a1d47b41eec4318b9a33f7 Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Thu, 22 Aug 2013 12:07:10 +0800 Subject: [PATCH 077/170] configure.ac: don't add RPATH when searching for extra libs Closes #766 doesn't appear to actually be required, and adding RPATH breaks Debian and OpenSUSE policy all flames to me --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6a42e6007..44b589bea 100644 --- a/configure.ac +++ b/configure.ac @@ -126,7 +126,7 @@ for i in /usr/pkg /sw /opt /opt/local /usr/local; do AC_MSG_CHECKING([for $i/lib library directory]) if test -d $i/lib; then AC_MSG_RESULT(yes) - LDFLAGS="$LDFLAGS -L$i/lib/ -Wl,-rpath,$i/lib/" + LDFLAGS="$LDFLAGS -L$i/lib/" else AC_MSG_RESULT(no) fi From b6f495d1077b7627ea851da33936c77b2d594bb2 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 24 Aug 2013 11:16:45 -0700 Subject: [PATCH 078/170] Expand abbreviations at the beginning of commands as discussed in https://github.com/fish-shell/fish-shell/issues/731 --- reader.cpp | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/reader.cpp b/reader.cpp index 96d7bc44d..80d60fb88 100644 --- a/reader.cpp +++ b/reader.cpp @@ -249,8 +249,8 @@ public: /** Do what we need to do whenever our command line changes */ void command_line_changed(void); - /** Expand abbreviations at the current cursor position. */ - bool expand_abbreviation_as_necessary(); + /** Expand abbreviations at the current cursor position, minus backtrack_amt. */ + bool expand_abbreviation_as_necessary(size_t cursor_backtrack); /** The current position of the cursor in buff. */ size_t buff_pos; @@ -660,7 +660,7 @@ bool reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t curso const wcstring subcmd = wcstring(cmdsub_begin, cmdsub_end - cmdsub_begin); const wchar_t *subcmd_cstr = subcmd.c_str(); - /* Get the token before the cursor */ + /* Get the token containing the cursor */ const wchar_t *subcmd_tok_begin = NULL, *subcmd_tok_end = NULL; assert(cursor_pos >= subcmd_offset); size_t subcmd_cursor_pos = cursor_pos - subcmd_offset; @@ -776,15 +776,16 @@ bool reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t curso return result; } -/* Expand abbreviations. This may change the command line but does NOT repaint it. This is to allow the caller to coalesce repaints. */ -bool reader_data_t::expand_abbreviation_as_necessary() +/* Expand abbreviations at the current cursor position, minus the given cursor backtrack. This may change the command line but does NOT repaint it. This is to allow the caller to coalesce repaints. */ +bool reader_data_t::expand_abbreviation_as_necessary(size_t cursor_backtrack) { bool result = false; if (this->expand_abbreviations) { /* Try expanding abbreviations */ wcstring new_cmdline; - if (reader_expand_abbreviation_in_command(this->command_line, this->buff_pos, &new_cmdline)) + size_t cursor_pos = this->buff_pos - mini(this->buff_pos, cursor_backtrack); + if (reader_expand_abbreviation_in_command(this->command_line, cursor_pos, &new_cmdline)) { /* We expanded an abbreviation! The cursor moves by the difference in the command line lengths. */ size_t new_buff_pos = this->buff_pos + new_cmdline.size() - this->command_line.size(); @@ -1078,34 +1079,38 @@ static void remove_backward() /** Insert the characters of the string into the command line buffer and print them to the screen using syntax highlighting, etc. + Optionally also expand abbreviations. + Returns true if the string changed. */ -static int insert_string(const wcstring &str) +static bool insert_string(const wcstring &str, bool should_expand_abbreviations = false) { size_t len = str.size(); if (len == 0) - return 0; + return false; data->command_line.insert(data->buff_pos, str); data->buff_pos += len; data->command_line_changed(); data->suppress_autosuggestion = false; + if (should_expand_abbreviations) + data->expand_abbreviation_as_necessary(1); + /* Syntax highlight. Note we must have that buff_pos > 0 because we just added something nonzero to its length */ assert(data->buff_pos > 0); reader_super_highlight_me_plenty(data->buff_pos-1); - reader_repaint(); - return 1; -} + return true; +} /** Insert the character into the command line buffer and print it to the screen using syntax highlighting, etc. */ -static int insert_char(wchar_t c) +static bool insert_char(wchar_t c, bool should_expand_abbreviations = false) { - return insert_string(wcstring(&c, 1)); + return insert_string(wcstring(1, c), should_expand_abbreviations); } @@ -3439,7 +3444,7 @@ const wchar_t *reader_readline(void) if (command_test_result == 0 || command_test_result == PARSER_TEST_INCOMPLETE) { /* This command is valid, but an abbreviation may make it invalid. If so, we will have to test again. */ - bool abbreviation_expanded = data->expand_abbreviation_as_necessary(); + bool abbreviation_expanded = data->expand_abbreviation_as_necessary(1); if (abbreviation_expanded) { /* It's our reponsibility to rehighlight and repaint. But everything we do below triggers a repaint. */ @@ -3786,14 +3791,11 @@ const wchar_t *reader_readline(void) { if ((!wchar_private(c)) && (((c>31) || (c==L'\n'))&& (c != 127))) { - /* Expand abbreviations on space */ - if (c == L' ') - { - data->expand_abbreviation_as_necessary(); - } + /* Expand abbreviations after space */ + bool should_expand_abbreviations = (c == L' '); /* Regular character */ - insert_char(c); + insert_char(c, should_expand_abbreviations); } else { From 9a49b2c9fb74fccd56a1ee8ee9a3a6db29afcb56 Mon Sep 17 00:00:00 2001 From: nulltrek Date: Thu, 22 Aug 2013 22:57:30 +0200 Subject: [PATCH 079/170] Fix "command not found" handler behaviour. --- share/functions/__fish_config_interactive.fish | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/functions/__fish_config_interactive.fish b/share/functions/__fish_config_interactive.fish index d7961861f..4f873d927 100644 --- a/share/functions/__fish_config_interactive.fish +++ b/share/functions/__fish_config_interactive.fish @@ -222,12 +222,12 @@ function __fish_config_interactive -d "Initializations that should be performed # First check in /usr/lib, this is where modern Ubuntus place this command if test -f /usr/lib/command-not-found function fish_command_not_found_handler --on-event fish_command_not_found - /usr/lib/command-not-found $argv + /usr/lib/command-not-found -- $argv end # Ubuntu Feisty places this command in the regular path instead else if type -p command-not-found > /dev/null 2> /dev/null function fish_command_not_found_handler --on-event fish_command_not_found - command-not-found $argv + command-not-found -- $argv end # Use standard fish command not found handler otherwise else From 8605cc685ddcf9adc1a4044b37178fd3e985c8bd Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 24 Aug 2013 12:20:21 -0700 Subject: [PATCH 080/170] Fix tabs in share/functions/__fish_config_interactive.fish --- share/functions/__fish_config_interactive.fish | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/functions/__fish_config_interactive.fish b/share/functions/__fish_config_interactive.fish index 4f873d927..ab1a6837d 100644 --- a/share/functions/__fish_config_interactive.fish +++ b/share/functions/__fish_config_interactive.fish @@ -222,12 +222,12 @@ function __fish_config_interactive -d "Initializations that should be performed # First check in /usr/lib, this is where modern Ubuntus place this command if test -f /usr/lib/command-not-found function fish_command_not_found_handler --on-event fish_command_not_found - /usr/lib/command-not-found -- $argv + /usr/lib/command-not-found -- $argv end # Ubuntu Feisty places this command in the regular path instead else if type -p command-not-found > /dev/null 2> /dev/null function fish_command_not_found_handler --on-event fish_command_not_found - command-not-found -- $argv + command-not-found -- $argv end # Use standard fish command not found handler otherwise else From a8af97489549ef737b1518888545c9fedcf380ef Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 25 Aug 2013 00:44:22 -0700 Subject: [PATCH 081/170] Fix a C++11 compile error with clang. https://github.com/mxcl/homebrew/pull/22016#issuecomment-23222977 --- exec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exec.cpp b/exec.cpp index dbfb66669..daad09f7f 100644 --- a/exec.cpp +++ b/exec.cpp @@ -376,7 +376,7 @@ static void launch_process_nofork(process_t *p) */ static int has_fd(const io_chain_t &d, int fd) { - return io_chain_get(d, fd) != NULL; + return io_chain_get(d, fd).get() != NULL; } /** From dead45fa67773324ec136acc37184e40af3cfe9f Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 25 Aug 2013 13:25:24 -0700 Subject: [PATCH 082/170] Rearrange the PATH to respect the order defined in /etc/paths (#927) and to prepend it to $PATH instead of appending it (#950) --- share/config.fish | 57 +++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/share/config.fish b/share/config.fish index 2c1f8b526..e7ca703f4 100644 --- a/share/config.fish +++ b/share/config.fish @@ -57,41 +57,44 @@ if test -d /usr/xpg4/bin end end +# OS X-ism: Load the path files out of /etc/paths and /etc/paths.d/* +set -g __fish_tmp_path $PATH +function __fish_load_path_helper_paths + while read -l new_path_comp + # We want to rearrange the path to reflect this order. Delete that path component if it exists and then prepend it. + set -l where (contains -i $new_path_comp $__fish_tmp_path) + and set -e __fish_tmp_path[$where] + set __fish_tmp_path $new_path_comp $__fish_tmp_path + end +end +test -r /etc/paths ; and __fish_load_path_helper_paths < /etc/paths +for pathfile in /etc/paths.d/* ; __fish_load_path_helper_paths < $pathfile ; end +set -xg PATH $__fish_tmp_path +set -e __fish_tmp_path +functions -e __fish_load_path_helper_paths + + # Add a handler for when fish_user_path changes, so we can apply the same changes to PATH # Invoke it immediately to apply the current value of fish_user_path function __fish_reconstruct_path -d "Update PATH when fish_user_paths changes" --on-variable fish_user_paths - set -l local_path $PATH - set -l x - for x in $__fish_added_user_paths - if set -l idx (contains --index $x $local_path) - set -e local_path[$idx] - end + set -l local_path $PATH + set -l x + for x in $__fish_added_user_paths + set -l idx (contains --index $x $local_path) + and set -e local_path[$idx] end - set -e __fish_added_user_paths - for x in $fish_user_paths[-1..1] - if not contains $x $local_path - set local_path $x $local_path - set -g __fish_added_user_paths $__fish_added_user_paths $x - end - end - set -xg PATH $local_path + set -e __fish_added_user_paths + for x in $fish_user_paths[-1..1] + if not contains $x $local_path + set local_path $x $local_path + set -g __fish_added_user_paths $__fish_added_user_paths $x + end + end + set -xg PATH $local_path end __fish_reconstruct_path -# OS X-ism: Load the path files out of /etc/paths and /etc/paths.d/* -function __fish_load_path_helper_paths - while read -l new_path_comp - if not contains $new_path_comp $PATH - set PATH $PATH $new_path_comp - end - end -end -if test -r /etc/paths ; __fish_load_path_helper_paths < /etc/paths ; end -for pathfile in /etc/paths.d/* ; __fish_load_path_helper_paths < $pathfile ; end -functions -e __fish_load_path_helper_paths - - # # Launch debugger on SIGTRAP # From 9f46881c16af03b52b9daba7c645100f180b7a8f Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 25 Aug 2013 14:00:56 -0700 Subject: [PATCH 083/170] Fix to respect the order of paths in /etc/paths (oops) --- share/config.fish | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/share/config.fish b/share/config.fish index e7ca703f4..6b62a01c3 100644 --- a/share/config.fish +++ b/share/config.fish @@ -60,12 +60,15 @@ end # OS X-ism: Load the path files out of /etc/paths and /etc/paths.d/* set -g __fish_tmp_path $PATH function __fish_load_path_helper_paths + # We want to rearrange the path to reflect this order. Delete that path component if it exists and then prepend it. + # Since we are prepending but want to preserve the order of the input file, we reverse the array, append, and then reverse it again + set __fish_tmp_path $__fish_tmp_path[-1..1] while read -l new_path_comp - # We want to rearrange the path to reflect this order. Delete that path component if it exists and then prepend it. - set -l where (contains -i $new_path_comp $__fish_tmp_path) + set -l where (contains -i $new_path_comp $__fish_tmp_path) and set -e __fish_tmp_path[$where] set __fish_tmp_path $new_path_comp $__fish_tmp_path end + set __fish_tmp_path $__fish_tmp_path[-1..1] end test -r /etc/paths ; and __fish_load_path_helper_paths < /etc/paths for pathfile in /etc/paths.d/* ; __fish_load_path_helper_paths < $pathfile ; end From 1d67d8ff23669814ed92d5d328a65174bfc72efd Mon Sep 17 00:00:00 2001 From: Tony Wang Date: Fri, 23 Aug 2013 22:54:24 +0800 Subject: [PATCH 084/170] add -O and -G to test command they are available on Linux and OS X, and now ported to fish --- builtin_test.cpp | 34 ++++++++++++++++++++++------------ doc_src/test.txt | 2 ++ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/builtin_test.cpp b/builtin_test.cpp index 1cf798960..2fd3f916d 100644 --- a/builtin_test.cpp +++ b/builtin_test.cpp @@ -33,13 +33,15 @@ enum token_t test_bang, // "!", inverts sense test_filetype_b, // "-b", for block special files - test_filetype_c, // "-c" for character special files - test_filetype_d, // "-d" for directories - test_filetype_e, // "-e" for files that exist - test_filetype_f, // "-f" for for regular files - test_filetype_g, // "-g" for set-group-id - test_filetype_h, // "-h" for symbolic links + test_filetype_c, // "-c", for character special files + test_filetype_d, // "-d", for directories + test_filetype_e, // "-e", for files that exist + test_filetype_f, // "-f", for for regular files + test_filetype_G, // "-G", for check effective group id + test_filetype_g, // "-g", for set-group-id + test_filetype_h, // "-h", for symbolic links test_filetype_L, // "-L", same as -h + test_filetype_O, // "-O", for check effective user id test_filetype_p, // "-p", for FIFO test_filetype_S, // "-S", socket @@ -95,9 +97,11 @@ static const struct token_info_t {test_filetype_d, L"-d", UNARY_PRIMARY}, {test_filetype_e, L"-e", UNARY_PRIMARY}, {test_filetype_f, L"-f", UNARY_PRIMARY}, + {test_filetype_G, L"-G", UNARY_PRIMARY}, {test_filetype_g, L"-g", UNARY_PRIMARY}, {test_filetype_h, L"-h", UNARY_PRIMARY}, {test_filetype_L, L"-L", UNARY_PRIMARY}, + {test_filetype_O, L"-O", UNARY_PRIMARY}, {test_filetype_p, L"-p", UNARY_PRIMARY}, {test_filetype_S, L"-S", UNARY_PRIMARY}, {test_filesize_s, L"-s", UNARY_PRIMARY}, @@ -812,25 +816,31 @@ static bool unary_primary_evaluate(test_expressions::token_t token, const wcstri case test_filetype_b: // "-b", for block special files return !wstat(arg, &buf) && S_ISBLK(buf.st_mode); - case test_filetype_c: // "-c" for character special files + case test_filetype_c: // "-c", for character special files return !wstat(arg, &buf) && S_ISCHR(buf.st_mode); - case test_filetype_d: // "-d" for directories + case test_filetype_d: // "-d", for directories return !wstat(arg, &buf) && S_ISDIR(buf.st_mode); - case test_filetype_e: // "-e" for files that exist + case test_filetype_e: // "-e", for files that exist return !wstat(arg, &buf); - case test_filetype_f: // "-f" for for regular files + case test_filetype_f: // "-f", for for regular files return !wstat(arg, &buf) && S_ISREG(buf.st_mode); - case test_filetype_g: // "-g" for set-group-id + case test_filetype_G: // "-G", for check effective group id + return !lwstat(arg, &buf) && getegid() == buf.st_gid; + + case test_filetype_g: // "-g", for set-group-id return !wstat(arg, &buf) && (S_ISGID & buf.st_mode); - case test_filetype_h: // "-h" for symbolic links + case test_filetype_h: // "-h", for symbolic links case test_filetype_L: // "-L", same as -h return !lwstat(arg, &buf) && S_ISLNK(buf.st_mode); + case test_filetype_O: // "-O", for check effective user id + return !lwstat(arg, &buf) && geteuid() == buf.st_uid; + case test_filetype_p: // "-p", for FIFO return !wstat(arg, &buf) && S_ISFIFO(buf.st_mode); diff --git a/doc_src/test.txt b/doc_src/test.txt index fc64118e7..035671325 100644 --- a/doc_src/test.txt +++ b/doc_src/test.txt @@ -16,7 +16,9 @@ The following operators are available to examine files and directories: - -e FILE returns true if \c FILE exists. - -f FILE returns true if \c FILE is a regular file. - -g FILE returns true if \c FILE has the set-group-ID bit set. +- -G FILE returns true if \c FILE exists and its group matches the effective group id of this process. - -L FILE returns true if \c FILE is a symbolic link. +- -O FILE returns true if \c FILE exists and its owner matches the effective user id of this process. - -p FILE returns true if \c FILE is a named pipe. - -r FILE returns true if \c FILE is marked as readable. - -s FILE returns true if the size of \c FILE is greater than zero. From 5559962f6f584e3bce45e29676ef2d0c44e36124 Mon Sep 17 00:00:00 2001 From: Tony Wang Date: Sun, 25 Aug 2013 09:10:19 +0800 Subject: [PATCH 085/170] use wstat in test command to follow symbolic link --- builtin_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builtin_test.cpp b/builtin_test.cpp index 2fd3f916d..0d16823af 100644 --- a/builtin_test.cpp +++ b/builtin_test.cpp @@ -829,7 +829,7 @@ static bool unary_primary_evaluate(test_expressions::token_t token, const wcstri return !wstat(arg, &buf) && S_ISREG(buf.st_mode); case test_filetype_G: // "-G", for check effective group id - return !lwstat(arg, &buf) && getegid() == buf.st_gid; + return !wstat(arg, &buf) && getegid() == buf.st_gid; case test_filetype_g: // "-g", for set-group-id return !wstat(arg, &buf) && (S_ISGID & buf.st_mode); @@ -839,7 +839,7 @@ static bool unary_primary_evaluate(test_expressions::token_t token, const wcstri return !lwstat(arg, &buf) && S_ISLNK(buf.st_mode); case test_filetype_O: // "-O", for check effective user id - return !lwstat(arg, &buf) && geteuid() == buf.st_uid; + return !wstat(arg, &buf) && geteuid() == buf.st_uid; case test_filetype_p: // "-p", for FIFO return !wstat(arg, &buf) && S_ISFIFO(buf.st_mode); From 7e1a3148fb373fc1c75c2350f1a256b4f06bea1f Mon Sep 17 00:00:00 2001 From: Tony Wang Date: Sun, 18 Aug 2013 10:43:13 +0800 Subject: [PATCH 086/170] fixed fish-shell/fish-shell#944 When the completion list includes the exact typed string with other candidates, i.e. completion_t.match.type == fuzzy_match_exact, the other candidates will be removed from the list, as they are not the "best type". This is inconvenient for the user who wants to type and complete commands in the other candidates. The commit is to make the best_type to fuzzy_match_prefix as highest priority, also, when comparing to best_type, the same or higher priority completions can both match. --- reader.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/reader.cpp b/reader.cpp index 80d60fb88..8045467e8 100644 --- a/reader.cpp +++ b/reader.cpp @@ -1665,12 +1665,16 @@ static void prioritize_completions(std::vector &comp) if (el.match.type < best_type) best_type = el.match.type; } + if (best_type == fuzzy_match_exact) + { + best_type = fuzzy_match_prefix; + } /* Throw out completions whose match types are not the best. */ i = comp.size(); while (i--) { - if (comp.at(i).match.type != best_type) + if (comp.at(i).match.type > best_type) { comp.erase(comp.begin() + i); } @@ -1796,13 +1800,17 @@ static bool handle_completions(const std::vector &comp) best_match_type = el.match.type; } } + if (best_match_type == fuzzy_match_exact) + { + best_match_type = fuzzy_match_prefix; + } /* Determine whether we are going to replace the token or not. If any commands of the best type do not require replacement, then ignore all those that want to use replacement */ bool will_replace_token = true; for (size_t i=0; i< comp.size(); i++) { const completion_t &el = comp.at(i); - if (el.match.type == best_match_type && !(el.flags & COMPLETE_REPLACES_TOKEN)) + if (el.match.type <= best_match_type && !(el.flags & COMPLETE_REPLACES_TOKEN)) { will_replace_token = false; break; @@ -1815,7 +1823,7 @@ static bool handle_completions(const std::vector &comp) { const completion_t &el = comp.at(i); /* Only use completions with the best match type */ - if (el.match.type != best_match_type) + if (el.match.type > best_match_type) continue; /* Only use completions that match replace_token */ From d2ffdc8986996c55aba7c59efe96022cdfa2e99b Mon Sep 17 00:00:00 2001 From: Tony Wang Date: Sun, 25 Aug 2013 17:10:22 +0800 Subject: [PATCH 087/170] improve comments and extract a common function --- reader.cpp | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/reader.cpp b/reader.cpp index 8045467e8..3a444902f 100644 --- a/reader.cpp +++ b/reader.cpp @@ -1653,25 +1653,35 @@ bool compare_completions_by_match_type(const completion_t &a, const completion_t return wcsfilecmp(a.completion.c_str(), b.completion.c_str()) < 0; } -/* Order completions such that case insensitive completions come first. */ -static void prioritize_completions(std::vector &comp) +/* Determine the best match type */ +fuzzy_match_type_t get_best_match_type(const std::vector &comp) { - /* Determine the best match type */ - size_t i; fuzzy_match_type_t best_type = fuzzy_match_none; - for (i=0; i < comp.size(); i++) + for (size_t i=0; i < comp.size(); i++) { const completion_t &el = comp.at(i); if (el.match.type < best_type) + { best_type = el.match.type; + } } + /* For case exact match as best type, make it to lower level as prefix match, + because completions with prefix match cannot stay otherwise while they are + also candidates of the input along with completion with exact match. */ if (best_type == fuzzy_match_exact) { best_type = fuzzy_match_prefix; } + return best_type; +} - /* Throw out completions whose match types are not the best. */ - i = comp.size(); +/* Order completions such that case insensitive completions come first. */ +static void prioritize_completions(std::vector &comp) +{ + fuzzy_match_type_t best_type = get_best_match_type(comp); + + /* Throw out completions whose match types are less suitable than the best. */ + size_t i = comp.size(); while (i--) { if (comp.at(i).match.type > best_type) @@ -1789,21 +1799,7 @@ static bool handle_completions(const std::vector &comp) if (!done) { - - /* Determine the type of the best match(es) */ - fuzzy_match_type_t best_match_type = fuzzy_match_none; - for (size_t i=0; i < comp.size(); i++) - { - const completion_t &el = comp.at(i); - if (el.match.type < best_match_type) - { - best_match_type = el.match.type; - } - } - if (best_match_type == fuzzy_match_exact) - { - best_match_type = fuzzy_match_prefix; - } + fuzzy_match_type_t best_match_type = get_best_match_type(comp); /* Determine whether we are going to replace the token or not. If any commands of the best type do not require replacement, then ignore all those that want to use replacement */ bool will_replace_token = true; @@ -1822,7 +1818,7 @@ static bool handle_completions(const std::vector &comp) for (size_t i=0; i < comp.size(); i++) { const completion_t &el = comp.at(i); - /* Only use completions with the best match type */ + /* Ignore completions with less suitable match type than the best. */ if (el.match.type > best_match_type) continue; From 06b4964dd8a955dc3e586efa0a7b59f576f22a27 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 26 Aug 2013 00:05:23 -0700 Subject: [PATCH 088/170] Clean up some comments and make a function static --- reader.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/reader.cpp b/reader.cpp index 3a444902f..8b4c79836 100644 --- a/reader.cpp +++ b/reader.cpp @@ -1653,8 +1653,8 @@ bool compare_completions_by_match_type(const completion_t &a, const completion_t return wcsfilecmp(a.completion.c_str(), b.completion.c_str()) < 0; } -/* Determine the best match type */ -fuzzy_match_type_t get_best_match_type(const std::vector &comp) +/* Determine the best match type for a set of completions */ +static fuzzy_match_type_t get_best_match_type(const std::vector &comp) { fuzzy_match_type_t best_type = fuzzy_match_none; for (size_t i=0; i < comp.size(); i++) @@ -1665,9 +1665,7 @@ fuzzy_match_type_t get_best_match_type(const std::vector &comp) best_type = el.match.type; } } - /* For case exact match as best type, make it to lower level as prefix match, - because completions with prefix match cannot stay otherwise while they are - also candidates of the input along with completion with exact match. */ + /* If the best type is an exact match, reduce it to prefix match. Otherwise a tab completion will only show one match if it matches a file exactly. (see issue #959) */ if (best_type == fuzzy_match_exact) { best_type = fuzzy_match_prefix; @@ -1818,7 +1816,7 @@ static bool handle_completions(const std::vector &comp) for (size_t i=0; i < comp.size(); i++) { const completion_t &el = comp.at(i); - /* Ignore completions with less suitable match type than the best. */ + /* Ignore completions with a less suitable match type than the best. */ if (el.match.type > best_match_type) continue; From 7a1bedcab6f216e330f7878cfe227eb7bfe33956 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Mon, 26 Aug 2013 16:24:59 +0200 Subject: [PATCH 089/170] Fix #976. Now prompt tries to use standard git command. --- share/functions/__fish_git_prompt.fish | 36 +++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/share/functions/__fish_git_prompt.fish b/share/functions/__fish_git_prompt.fish index 0515f16f6..4ca32c6eb 100644 --- a/share/functions/__fish_git_prompt.fish +++ b/share/functions/__fish_git_prompt.fish @@ -186,7 +186,7 @@ function __fish_git_prompt_show_upstream --description "Helper function for __fi set -l svn_remote # get some config options from git-config - git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' ^/dev/null | tr '\0\n' '\n ' | while read -l key value + command git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' ^/dev/null | tr '\0\n' '\n ' | while read -l key value switch $key case bash.showupstream set show_upstream $value @@ -261,7 +261,7 @@ function __fish_git_prompt_show_upstream --description "Helper function for __fi set upstream (/bin/sh -c 'val=${1#/branches}; echo "${val#/}"' -- $svn_upstream) # Use fetch config to fix upstream - set -l fetch_val (git config "$cur_prefix".fetch) + set -l fetch_val (command git config "$cur_prefix".fetch) if test -n "$fetch_val" set -l IFS : echo "$fetch_val" | read -l trunk pattern @@ -275,11 +275,11 @@ function __fish_git_prompt_show_upstream --description "Helper function for __fi # Find how many commits we are ahead/behind our upstream if test -z "$legacy" - set count (git rev-list --count --left-right $upstream...HEAD ^/dev/null) + set count (command git rev-list --count --left-right $upstream...HEAD ^/dev/null) else # produce equivalent output to --count for older versions of git set -l os - set -l commits (git rev-list --left-right $upstream...HEAD ^/dev/null; set os $status) + set -l commits (command git rev-list --left-right $upstream...HEAD ^/dev/null; set os $status) if test $os -eq 0 set -l behind (count (for arg in $commits; echo $arg; end | grep '^<')) set -l ahead (count (for arg in $commits; echo $arg; end | grep -v '^<')) @@ -331,7 +331,7 @@ function __fish_git_prompt_show_upstream --description "Helper function for __fi end function __fish_git_prompt --description "Prompt function for Git" - set -l repo_info (git rev-parse --git-dir --is-inside-git-dir --is-bare-repository --is-inside-work-tree --short HEAD ^/dev/null) + set -l repo_info (command git rev-parse --git-dir --is-inside-git-dir --is-bare-repository --is-inside-work-tree --short HEAD ^/dev/null) test -n "$repo_info"; or return set -l git_dir $repo_info[1] @@ -362,7 +362,7 @@ function __fish_git_prompt --description "Prompt function for Git" set informative_status "$___fish_git_prompt_char_stateseparator"(__fish_git_prompt_informative_status) else if test -n "$__fish_git_prompt_showdirtystate" - set -l config (git config --bool bash.showDirtyState) + set -l config (command git config --bool bash.showDirtyState) if test "$config" != "false" set w (__fish_git_prompt_dirty) set i (__fish_git_prompt_staged $short_sha) @@ -374,9 +374,9 @@ function __fish_git_prompt --description "Prompt function for Git" end if test -n "$__fish_git_prompt_showuntrackedfiles" - set -l config (git config --bool bash.showUntrackedFiles) + set -l config (command git config --bool bash.showUntrackedFiles) if test "$config" != false - if git ls-files --others --exclude-standard --error-unmatch -- '*' >/dev/null ^/dev/null + if command git ls-files --others --exclude-standard --error-unmatch -- '*' >/dev/null ^/dev/null set u $___fish_git_prompt_char_untrackedfiles end end @@ -447,7 +447,7 @@ function __fish_git_prompt_staged --description "__fish_git_prompt helper, tells set -l staged if test -n "$short_sha" - git diff-index --cached --quiet HEAD --; or set staged $___fish_git_prompt_char_stagedstate + command git diff-index --cached --quiet HEAD --; or set staged $___fish_git_prompt_char_stagedstate else set staged $___fish_git_prompt_char_invalidstate end @@ -458,7 +458,7 @@ function __fish_git_prompt_dirty --description "__fish_git_prompt helper, tells set -l dirty set -l os - git diff --no-ext-diff --quiet --exit-code + command git diff --no-ext-diff --quiet --exit-code set os $status if test $os -ne 0 set dirty $___fish_git_prompt_char_dirtystate @@ -470,13 +470,13 @@ set -g ___fish_git_prompt_status_order stagedstate invalidstate dirtystate untra function __fish_git_prompt_informative_status - set -l changedFiles (git diff --name-status | cut -c 1-2) - set -l stagedFiles (git diff --staged --name-status | cut -c 1-2) + set -l changedFiles (command git diff --name-status | cut -c 1-2) + set -l stagedFiles (command git diff --staged --name-status | cut -c 1-2) set -l dirtystate (math (count $changedFiles) - (count (echo $changedFiles | grep "U"))) set -l invalidstate (count (echo $stagedFiles | grep "U")) set -l stagedstate (math (count $stagedFiles) - $invalidstate) - set -l untrackedfiles (count (git ls-files --others --exclude-standard)) + set -l untrackedfiles (count (command git ls-files --others --exclude-standard)) set -l info @@ -564,18 +564,18 @@ function __fish_git_prompt_operation_branch_bare --description "__fish_git_promp end if test -z "$branch" - set branch (git symbolic-ref HEAD ^/dev/null; set os $status) + set branch (command git symbolic-ref HEAD ^/dev/null; set os $status) if test $os -ne 0 set detached yes set branch (switch "$__fish_git_prompt_describe_style" case contains - git describe --contains HEAD + command git describe --contains HEAD case branch - git describe --contains --all HEAD + command git describe --contains --all HEAD case describe - git describe HEAD + command git describe HEAD case default '*' - git describe --tags --exact-match HEAD + command git describe --tags --exact-match HEAD end ^/dev/null; set os $status) if test $os -ne 0 if test -n "$short_sha" From ec1037fcbc3c7a4c85f540a6b931d5e80cf25fd2 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 26 Aug 2013 21:10:02 -0700 Subject: [PATCH 090/170] Fix bad error message for certain options. https://github.com/fish-shell/fish-shell/issues/979 --- wgetopt.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/wgetopt.cpp b/wgetopt.cpp index 8e114117b..08ccc3b14 100644 --- a/wgetopt.cpp +++ b/wgetopt.cpp @@ -638,6 +638,7 @@ _wgetopt_internal(int argc, wchar_t *const *argv, const wchar_t *optstring, cons fwprintf(stderr, _(L"%ls: Invalid option -- %lc\n"), argv[0], c); } woptopt = c; + woptind++; return '?'; } if (temp[1] == ':') From 85ce80d72e666d51b52f8a54e8143062478286e4 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Tue, 27 Aug 2013 18:23:33 -0700 Subject: [PATCH 091/170] Stop insisting on trying to add /usr/bin and /bin to $PATH. https://github.com/fish-shell/fish-shell/pull/854 --- env.cpp | 63 +++++---------------------------------------------------- 1 file changed, 5 insertions(+), 58 deletions(-) diff --git a/env.cpp b/env.cpp index a99f18121..13f87b6cc 100644 --- a/env.cpp +++ b/env.cpp @@ -429,68 +429,15 @@ static void universal_callback(fish_message_type_t type, } /** - Make sure the PATH variable contains the essential directories + Make sure the PATH variable contains something */ static void setup_path() { - const wchar_t *path_el[] = + const env_var_t path = env_get_string(L"PATH"); + if (path.missing_or_empty()) { - L"/bin", - L"/usr/bin", - NULL - }; - - env_var_t path = env_get_string(L"PATH"); - - wcstring_list_t lst; - if (! path.missing()) - { - tokenize_variable_array(path, lst); - } - - for (size_t j=0; path_el[j] != NULL; j++) - { - - bool has_el = false; - - for (size_t i=0; i 0) && (el.at(len-1)==L'/')) - { - len--; - } - - if ((wcslen(path_el[j]) == len) && - (wcsncmp(el.c_str(), path_el[j], len)==0)) - { - has_el = true; - break; - } - } - - if (! has_el) - { - wcstring buffer; - - debug(3, L"directory %ls was missing", path_el[j]); - - if (!path.missing()) - { - buffer += path; - } - - buffer.append(ARRAY_SEP_STR); - buffer.append(path_el[j]); - - env_set(L"PATH", buffer.empty()?NULL:buffer.c_str(), ENV_GLOBAL | ENV_EXPORT); - - path = env_get_string(L"PATH"); - lst.resize(0); - tokenize_variable_array(path, lst); - } + const wchar_t *value = L"/usr/bin" ARRAY_SEP_STR L"/bin"; + env_set(L"PATH", value, ENV_GLOBAL | ENV_EXPORT); } } From 24f1da7f309f7e7077e265e1777c9da46ff65e37 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Tue, 27 Aug 2013 18:26:22 -0700 Subject: [PATCH 092/170] Add a fancy new paths_are_equivalent function to test for equivalent paths instead of merely equal ones --- fish_tests.cpp | 10 +++++--- path.cpp | 64 ++++++++++++++++++++++++++++++++++++++++---------- path.h | 3 +++ 3 files changed, 61 insertions(+), 16 deletions(-) diff --git a/fish_tests.cpp b/fish_tests.cpp index 41464c31a..b47ce3a3a 100644 --- a/fish_tests.cpp +++ b/fish_tests.cpp @@ -766,9 +766,8 @@ static void test_path() say(L"Testing path functions"); wcstring path = L"//foo//////bar/"; - wcstring canon = path; - path_make_canonical(canon); - if (canon != L"/foo/bar") + path_make_canonical(path); + if (path != L"/foo/bar") { err(L"Bug in canonical PATH code"); } @@ -779,6 +778,11 @@ static void test_path() { err(L"Bug in canonical PATH code"); } + + if (paths_are_equivalent(L"/foo/bar/baz", L"foo/bar/baz")) err(L"Bug in canonical PATH code on line %ld", (long)__LINE__); + if (! paths_are_equivalent(L"///foo///bar/baz", L"/foo/bar////baz//")) err(L"Bug in canonical PATH code on line %ld", (long)__LINE__); + if (! paths_are_equivalent(L"/foo/bar/baz", L"/foo/bar/baz")) err(L"Bug in canonical PATH code on line %ld", (long)__LINE__); + if (! paths_are_equivalent(L"/", L"/")) err(L"Bug in canonical PATH code on line %ld", (long)__LINE__); } enum word_motion_t diff --git a/path.cpp b/path.cpp index 73cfc0171..27aadbd3e 100644 --- a/path.cpp +++ b/path.cpp @@ -380,24 +380,62 @@ static void replace_all(wcstring &str, const wchar_t *needle, const wchar_t *rep void path_make_canonical(wcstring &path) { + // Ignore trailing slashes, unless it's the first character + size_t len = path.size(); + while (len > 1 && path.at(len - 1) == L'/') + len--; - /* Remove double slashes */ - size_t size; - do + // Turn runs of slashes into a single slash + size_t trailing = 0; + bool prev_was_slash = false; + for (size_t leading = 0; leading < len; leading++) { - size = path.size(); - replace_all(path, L"//", L"/"); - } - while (path.size() != size); + wchar_t c = path.at(leading); + bool is_slash = (c == '/'); + if (! prev_was_slash || ! is_slash) + { + // This is either the first slash in a run, or not a slash at all + path.at(trailing++) = c; + } + prev_was_slash = is_slash; + } + assert(trailing <= len); + if (trailing < len) + path.resize(trailing); +} - /* Remove trailing slashes, except don't remove the first one */ - while (size-- > 1) +bool paths_are_equivalent(const wcstring &p1, const wcstring &p2) +{ + if (p1 == p2) + return true; + + size_t len1 = p1.size(), len2 = p2.size(); + + // Ignore trailing slashes after the first character + while (len1 > 1 && p1.at(len1 - 1) == L'/') len1--; + while (len2 > 1 && p2.at(len2 - 1) == L'/') len2--; + + // Start walking + size_t idx1 = 0, idx2 = 0; + while (idx1 < len1 && idx2 < len2) { - if (path.at(size) != L'/') + wchar_t c1 = p1.at(idx1), c2 = p2.at(idx2); + + // If the characters are different, the strings are not equivalent + if (c1 != c2) break; + + idx1++; + idx2++; + + // If the character was a slash, walk forwards until we hit the end of the string, or a non-slash + // Note the first condition is invariant within the loop + while (c1 == L'/' && idx1 < len1 && p1.at(idx1) == L'/') idx1++; + while (c2 == L'/' && idx2 < len2 && p2.at(idx2) == L'/') idx2++; } - /* Now size is either -1 (if the entire string was slashes) or is the index of the last non-slash character. Either way this will set it to the correct size. */ - path.resize(size+1); + + // We matched if we consumed all of the characters in both strings + return idx1 == len1 && idx2 == len2; } bool path_is_valid(const wcstring &path, const wcstring &working_directory) @@ -433,7 +471,7 @@ bool path_is_valid(const wcstring &path, const wcstring &working_directory) bool paths_are_same_file(const wcstring &path1, const wcstring &path2) { - if (path1 == path2) + if (paths_are_equivalent(path1, path2)) return true; struct stat s1, s2; diff --git a/path.h b/path.h index a566501ef..b822f6e9c 100644 --- a/path.h +++ b/path.h @@ -73,6 +73,9 @@ bool path_can_be_implicit_cd(const wcstring &path, */ void path_make_canonical(wcstring &path); +/** Check if two paths are equivalent, which means to ignore runs of multiple slashes (or trailing slashes) */ +bool paths_are_equivalent(const wcstring &p1, const wcstring &p2); + bool path_is_valid(const wcstring &path, const wcstring &working_directory); /** Returns whether the two paths refer to the same file */ From 097e2030b4afcc5bab3cfdd4173b51462af85559 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Wed, 28 Aug 2013 09:35:22 +0200 Subject: [PATCH 093/170] libncursesw5-dev is not needed on Debian I just checked on new Debian installation, and only libncurses5-dev appears to be needed. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f1a34b400..d489eaf21 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ If fish reports that it could not find curses, try installing a curses developme On Debian or Ubuntu you want: - sudo apt-get install libncurses5-dev libncursesw5-dev + sudo apt-get install libncurses5-dev on RedHat, CentOS, or Amazon EC2: From da89591a5311b8e7fad6404e0fb0530a6e720613 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Thu, 29 Aug 2013 13:06:04 +0200 Subject: [PATCH 094/170] Initialize cycle_cursor_pos. This removes the warning from compiler. --- reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reader.cpp b/reader.cpp index 8b4c79836..11b45e9d2 100644 --- a/reader.cpp +++ b/reader.cpp @@ -3020,7 +3020,7 @@ const wchar_t *reader_readline(void) /* The command line before completion */ wcstring cycle_command_line; - size_t cycle_cursor_pos; + size_t cycle_cursor_pos = 0; data->search_buff.clear(); data->search_mode = NO_SEARCH; From 3a893ff17f8de898dbd58093cadffdaa65887b75 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Fri, 30 Aug 2013 18:10:23 +0200 Subject: [PATCH 095/170] Put an IRC link to README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d489eaf21..35ce6fa47 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,6 @@ Substitute /bin/bash with /bin/tcsh or /bin/zsh as appropriate. ## Contact Us -Questions, comments, rants and raves can be posted to the official fish mailing list at or join us on our IRC channel #fish at irc.oftc.net +Questions, comments, rants and raves can be posted to the official fish mailing list at or join us on our IRC channel [#fish at irc.oftc.net](irc://irc.oftc.net/fish). Found a bug? Have an awesome idea? Please open an issue on this github page. From 173fd4fd23ea4212ec41184c28e723b2f5f56e13 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Fri, 30 Aug 2013 18:12:50 +0200 Subject: [PATCH 096/170] Replace IRC link with WebChat link It seems GitHub doesn't allow irc:// protocol, so replace it with WebChat link. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 35ce6fa47..c0b8c69a8 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,6 @@ Substitute /bin/bash with /bin/tcsh or /bin/zsh as appropriate. ## Contact Us -Questions, comments, rants and raves can be posted to the official fish mailing list at or join us on our IRC channel [#fish at irc.oftc.net](irc://irc.oftc.net/fish). +Questions, comments, rants and raves can be posted to the official fish mailing list at or join us on our IRC channel [#fish at irc.oftc.net](https://webchat.oftc.net/?channels=fish). Found a bug? Have an awesome idea? Please open an issue on this github page. From 23ba7b5bfff9393d222cd8e4a045e3439e24aba1 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 31 Aug 2013 14:29:14 -0700 Subject: [PATCH 097/170] Support iTerm2 forward/backward word escapes (https://github.com/fish-shell/fish-shell/issues/920) --- share/functions/fish_default_key_bindings.fish | 2 ++ 1 file changed, 2 insertions(+) diff --git a/share/functions/fish_default_key_bindings.fish b/share/functions/fish_default_key_bindings.fish index 3a9b4785b..bebe3562c 100644 --- a/share/functions/fish_default_key_bindings.fish +++ b/share/functions/fish_default_key_bindings.fish @@ -74,6 +74,8 @@ function fish_default_key_bindings -d "Default (Emacs-like) key bindings for fis bind \ef forward-word bind \e\[1\;5C forward-word bind \e\[1\;5D backward-word + bind \e\[1\;9C forward-word #iTerm2 + bind \e\[1\;9D backward-word #iTerm2 bind \ed forward-kill-word bind -k ppage beginning-of-history bind -k npage end-of-history From c38a40d1930d0af2f0d078896fe02fd0bee5fabd Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 31 Aug 2013 15:01:02 -0700 Subject: [PATCH 098/170] Adjust prefix completions to sort alphabetically instead of by length. Other completions are still sorted by length. https://github.com/fish-shell/fish-shell/issues/923 --- complete.cpp | 24 ++++++++---------------- complete.h | 12 ++++-------- expand.cpp | 2 +- path.cpp | 1 + reader.cpp | 15 +++++++++------ 5 files changed, 23 insertions(+), 31 deletions(-) diff --git a/complete.cpp b/complete.cpp index 8fbcb1d34..ad2bbb143 100644 --- a/complete.cpp +++ b/complete.cpp @@ -312,20 +312,6 @@ completion_t &completion_t::operator=(const completion_t &him) return *this; } -bool completion_t::operator < (const completion_t& rhs) const -{ - return this->completion < rhs.completion; -} - -bool completion_t::operator == (const completion_t& rhs) const -{ - return this->completion == rhs.completion; -} - -bool completion_t::operator != (const completion_t& rhs) const -{ - return !(*this == rhs); -} wcstring_list_t completions_to_wcstring_list(const std::vector &list) { @@ -338,11 +324,17 @@ wcstring_list_t completions_to_wcstring_list(const std::vector &li return strings; } -void sort_completions(std::vector &completions) +bool completion_t::is_alphabetically_less_than(const completion_t &a, const completion_t &b) { - std::sort(completions.begin(), completions.end()); + return a.completion < b.completion; } +bool completion_t::is_alphabetically_equal_to(const completion_t &a, const completion_t &b) +{ + return a.completion == b.completion; +} + + /** Class representing an attempt to compute completions */ class completer_t { diff --git a/complete.h b/complete.h index da94bacdc..85208d69a 100644 --- a/complete.h +++ b/complete.h @@ -127,11 +127,10 @@ public: completion_t(const wcstring &comp, const wcstring &desc = L"", string_fuzzy_match_t match = string_fuzzy_match_t(fuzzy_match_exact), int flags_val = 0); completion_t(const completion_t &); completion_t &operator=(const completion_t &); - - /* The following are needed for sorting and uniquing completions */ - bool operator < (const completion_t& rhs) const; - bool operator == (const completion_t& rhs) const; - bool operator != (const completion_t& rhs) const; + + /* Compare two completions. No operating overlaoding to make this always explicit (there's potentially multiple ways to complare completions). */ + static bool is_alphabetically_less_than(const completion_t &a, const completion_t &b); + static bool is_alphabetically_equal_to(const completion_t &a, const completion_t &b); }; enum @@ -146,9 +145,6 @@ typedef uint32_t completion_request_flags_t; /** Given a list of completions, returns a list of their completion fields */ wcstring_list_t completions_to_wcstring_list(const std::vector &completions); -/** Sorts a list of completions */ -void sort_completions(std::vector &completions); - /** Add a completion. diff --git a/expand.cpp b/expand.cpp index dc83c385d..9dfe50266 100644 --- a/expand.cpp +++ b/expand.cpp @@ -1766,7 +1766,7 @@ int expand_string(const wcstring &input, std::vector &output, expa case 1: { res = EXPAND_WILDCARD_MATCH; - sort_completions(expanded); + std::sort(expanded.begin(), expanded.end(), completion_t::is_alphabetically_less_than); out->insert(out->end(), expanded.begin(), expanded.end()); break; } diff --git a/path.cpp b/path.cpp index 27aadbd3e..3a0b9c83d 100644 --- a/path.cpp +++ b/path.cpp @@ -367,6 +367,7 @@ bool path_get_config(wcstring &path) return ! result.empty(); } +__attribute__((unused)) static void replace_all(wcstring &str, const wchar_t *needle, const wchar_t *replacement) { size_t needle_len = wcslen(needle); diff --git a/reader.cpp b/reader.cpp index 11b45e9d2..cd9d9e450 100644 --- a/reader.cpp +++ b/reader.cpp @@ -802,8 +802,8 @@ bool reader_data_t::expand_abbreviation_as_necessary(size_t cursor_backtrack) /** Sorts and remove any duplicate completions in the list. */ static void sort_and_make_unique(std::vector &l) { - sort(l.begin(), l.end()); - l.erase(std::unique(l.begin(), l.end()), l.end()); + sort(l.begin(), l.end(), completion_t::is_alphabetically_less_than); + l.erase(std::unique(l.begin(), l.end(), completion_t::is_alphabetically_equal_to), l.end()); } @@ -1642,11 +1642,14 @@ static bool reader_can_replace(const wcstring &in, int flags) /* Compare two completions, ordering completions with better match types first */ bool compare_completions_by_match_type(const completion_t &a, const completion_t &b) { - /* Compare match types */ - int match_compare = a.match.compare(b.match); - if (match_compare != 0) + /* Compare match types, unless both completions are prefix (#923) in which case we always want to compare them alphabetically */ + if (a.match.type != fuzzy_match_prefix || b.match.type != fuzzy_match_prefix) { - return match_compare < 0; + int match_compare = a.match.compare(b.match); + if (match_compare != 0) + { + return match_compare < 0; + } } /* Compare using file comparison */ From 68f9342060b385c59fd92d465f82d319da32ecc8 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 31 Aug 2013 15:08:51 -0700 Subject: [PATCH 099/170] Try to improve the error message printed when libcurses is not found --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 44b589bea..1bff836da 100644 --- a/configure.ac +++ b/configure.ac @@ -479,7 +479,7 @@ LIBS="" AC_SEARCH_LIBS( connect, socket, , [AC_MSG_ERROR([Cannot find the socket library, needed to build this package.] )] ) AC_SEARCH_LIBS( nanosleep, rt, , [AC_MSG_ERROR([Cannot find the rt library, needed to build this package.] )] ) AC_SEARCH_LIBS( pthread_create, pthread, , [AC_MSG_ERROR([Cannot find the pthread library, needed to build this package.] )] ) -AC_SEARCH_LIBS( setupterm, [ncurses curses], , [AC_MSG_ERROR([Could not find a curses implementation, needed to build fish])] ) +AC_SEARCH_LIBS( setupterm, [ncurses curses], , [AC_MSG_ERROR([Could not find a curses implementation, needed to build fish. If this is Linux, try running 'sudo apt-get install libncurses5-dev' or 'sudo yum install ncurses-devel'])] ) AC_SEARCH_LIBS( [nan], [m], [AC_DEFINE( [HAVE_NAN], [1], [Define to 1 if you have the nan function])] ) LIBS_SHARED=$LIBS LIBS=$LIBS_COMMON From df0aaa1ebe6d0ca520a866be2f402d41bcad280c Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 31 Aug 2013 21:10:11 -0700 Subject: [PATCH 100/170] Fix indentation --- share/functions/fish_default_key_bindings.fish | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/functions/fish_default_key_bindings.fish b/share/functions/fish_default_key_bindings.fish index bebe3562c..3c4a745d4 100644 --- a/share/functions/fish_default_key_bindings.fish +++ b/share/functions/fish_default_key_bindings.fish @@ -74,8 +74,8 @@ function fish_default_key_bindings -d "Default (Emacs-like) key bindings for fis bind \ef forward-word bind \e\[1\;5C forward-word bind \e\[1\;5D backward-word - bind \e\[1\;9C forward-word #iTerm2 - bind \e\[1\;9D backward-word #iTerm2 + bind \e\[1\;9C forward-word #iTerm2 + bind \e\[1\;9D backward-word #iTerm2 bind \ed forward-kill-word bind -k ppage beginning-of-history bind -k npage end-of-history From 03aae474241bd91b4444997cf72c3e9181de07aa Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 31 Aug 2013 21:11:09 -0700 Subject: [PATCH 101/170] Fix more indentation in fish_default_key_bindings.fish --- share/functions/fish_default_key_bindings.fish | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/functions/fish_default_key_bindings.fish b/share/functions/fish_default_key_bindings.fish index 3c4a745d4..26db71d9c 100644 --- a/share/functions/fish_default_key_bindings.fish +++ b/share/functions/fish_default_key_bindings.fish @@ -83,13 +83,13 @@ function fish_default_key_bindings -d "Default (Emacs-like) key bindings for fis bind \e\> end-of-buffer bind \el __fish_list_current_token - bind \ew 'set tok (commandline -pt); if test $tok[1]; echo; whatis $tok[1]; commandline -f repaint; end' + bind \ew 'set tok (commandline -pt); if test $tok[1]; echo; whatis $tok[1]; commandline -f repaint; end' bind \cl 'clear; commandline -f repaint' bind \cc 'commandline ""' bind \cu backward-kill-line bind \ed kill-word bind \cw backward-kill-path-component - bind \ed 'set -l cmd (commandline); if test -z "$cmd"; echo; dirh; commandline -f repaint; else; commandline -f kill-word; end' + bind \ed 'set -l cmd (commandline); if test -z "$cmd"; echo; dirh; commandline -f repaint; else; commandline -f kill-word; end' bind \cd delete-or-exit # This will make sure the output of the current command is paged using the less pager when you press Meta-p From f230da12c564e74036ebbdb3a067b5e5c23e39af Mon Sep 17 00:00:00 2001 From: Adrien Grellier Date: Wed, 15 Apr 2009 09:26:55 +0100 Subject: [PATCH 102/170] completion for vim-addons --- share/completions/vim-addons.fish | 54 +++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 share/completions/vim-addons.fish diff --git a/share/completions/vim-addons.fish b/share/completions/vim-addons.fish new file mode 100644 index 000000000..67d5f48c7 --- /dev/null +++ b/share/completions/vim-addons.fish @@ -0,0 +1,54 @@ + +# Completion for vim-addons +# ========================= +# +# Adrien Grellier +# + +function __fish_vim-addons_subcommand --description 'Test if vim-addons has yet to be given the subcommand' + for i in (commandline -opc) + if contains -- $i list status install remove disable amend files show + return 1 + end + end + return 0 +end + +# Commands +# -------- +# list +complete -c vim-addons -n "__fish_vim-addons_subcommand" -a "list" -f -d "list the names of the addons available in the system" +# status +complete -c vim-addons -n "__fish_vim-addons_subcommand" -a "status" -f -d "show the status of the addons available in the system" +complete -c vim-addons -n "contains status (commandline -poc)" -a "(vim-addons list)" -x +# install +complete -c vim-addons -n "__fish_vim-addons_subcommand" -a "install" -x -d "install one or more addons under ~/.vim" +complete -c vim-addons -n "contains install (commandline -poc)" -a "(vim-addons status | awk '\$2 != \"installed\" && \$1 != \"#\" { print \$1}')" -x +# remove +complete -c vim-addons -n "__fish_vim-addons_subcommand" -a "remove" -x -d "remove one or more addons from ~/.vim" +complete -c vim-addons -n "contains remove (commandline -poc)" -a "(vim-addons status | awk '\$2 != \"removed\" && \$1 != \"#\" { print \$1}')" -x +# disable +complete -c vim-addons -n "__fish_vim-addons_subcommand" -a "disable" -x -d "disable one or more addons to be used by the current user" +complete -c vim-addons -n "contains disable (commandline -poc)" -a "(vim-addons status | awk '\$2 != \"disable\" && \$1 != \"#\" { print \$1}')" -x +# amend +complete -c vim-addons -n "__fish_vim-addons_subcommand" -a "amend" -x -d "undo the effects of a previous disable command" +complete -c vim-addons -n "contains amend (commandline -poc)" -a "(vim-addons list)" -x +# files +complete -c vim-addons -n "__fish_vim-addons_subcommand" -a "files" -x -d "list, one per line, the files composing the specified addons" +complete -c vim-addons -n "contains files (commandline -poc)" -a "(vim-addons list)" -x +# show +complete -c vim-addons -n "__fish_vim-addons_subcommand" -a "show" -x -d "displays detailed information about the specified addons" +complete -c vim-addons -n "contains show (commandline -poc)" -a "(vim-addons list)" -x + + +# Options +# -------- +complete -c vim-addons -s h -l help -d "show this usage message and exit" +complete -c vim-addons -s q -l query -d "be quiet and make the output more parseable" +complete -c vim-addons -s r -l registry-dir -d "set the registry directory" +complete -c vim-addons -s s -l source-dir -d "set the addons source directory" +complete -c vim-addons -s t -l target-dir -d "set the addons target directory" +complete -c vim-addons -s v -l verbose -d "increase verbosity" +complete -c vim-addons -s y -l system-dir -d "set the system-wide target directory" +complete -c vim-addons -s w -l system-wide -d "set target directory to the system-wide one" + From 16ba544edd188ed43c93214a908efc9862bc8bab Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Mon, 2 Sep 2013 13:05:55 +0800 Subject: [PATCH 103/170] docs: don't remove/rebuild share/man if we don't have doxygen --- Makefile.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile.in b/Makefile.in index 3c0eeffe2..7b243ee77 100644 --- a/Makefile.in +++ b/Makefile.in @@ -269,15 +269,17 @@ TRANSLATIONS := $(TRANSLATIONS_SRC:.po=.gmo) ifeq ($(HAVE_DOXYGEN), 1) user_doc=user_doc + share_man=share/man else user_doc= + share_man= endif # # Make everything needed for installing fish # -all: $(PROGRAMS) $(user_doc) share/man $(TRANSLATIONS) +all: $(PROGRAMS) $(user_doc) $(share_man) $(TRANSLATIONS) @echo fish has now been built. @echo Use \'$(MAKE) install\' to install fish. .PHONY: all @@ -828,7 +830,7 @@ clean: rm -f command_list.txt toc.txt rm -f doc_src/index.hdr doc_src/commands.hdr rm -f FISH-BUILD-VERSION-FILE - if test $(HAVE_DOXYGEN) = 1; then \ + if test "$(HAVE_DOXYGEN)" = 1; then \ rm -rf doc user_doc share/man; \ fi rm -f $(TRANSLATIONS) From cca60adc35c228178421c386b12d737048246877 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 2 Sep 2013 00:34:35 -0700 Subject: [PATCH 104/170] Fix useradd completion syntax (https://github.com/fish-shell/fish-shell/issues/863) --- share/completions/useradd.fish | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/share/completions/useradd.fish b/share/completions/useradd.fish index 3d12d51a4..dec568c88 100644 --- a/share/completions/useradd.fish +++ b/share/completions/useradd.fish @@ -9,14 +9,14 @@ complete -c useradd -s c -l comment --description 'A comment about this user' -r complete -c useradd -s d -l home --description 'Home directory for the new user' -x -a '(__fish_complete_directories)' complete -c useradd -s G -l groups --description 'Supplementary groups' -xa '(__fish_append , (cat /etc/group|cut -d : -f 1))' complete -c useradd -s h -l help --description 'Display help message and exit' -complete -c useradd -s m -l create-home --description 'The user's home directory will be created if it does not exist' +complete -c useradd -s m -l create-home --description 'The user\'s home directory will be created if it does not exist' complete -c useradd -s n --description 'A group having the same name as the user being added to the system will be created by default (when -g is not specified)' complete -c useradd -s K -l key --description 'Overrides default key/value pairs from /etc/login' complete -c useradd -s o -l non-unique --description 'Allow the creation of a user account with a duplicate (non-unique) UID' complete -c useradd -s p -l password --description 'The encrypted password, as returned by crypt(3)' -r -complete -c useradd -s u -l uid --description 'The numerical value of the user's ID' -r -complete -c useradd -s b -l base-dir --description 'The initial path prefix for a new user's home directory' -r -a '(__fish_complete_directories)' +complete -c useradd -s u -l uid --description 'The numerical value of the user\'s ID' -r +complete -c useradd -s b -l base-dir --description 'The initial path prefix for a new user\'s home directory' -r -a '(__fish_complete_directories)' complete -c useradd -s e -l expiredate --description 'The date on which the user account is disabled' -r complete -c useradd -s f -l inactive --description 'The number of days after a password has expired before the account will be disabled' -r -complete -c useradd -s g -l gid --description 'The group name or ID for a new user's initial group' -x -a '(cat /etc/group|cut -d : -f 1,3|sed -e "s/:/\n/")' -complete -c useradd -s s -l shell --description 'Name of the new user's login shell' -x -a '(cat /etc/shells)' +complete -c useradd -s g -l gid --description 'The group name or ID for a new user\'s initial group' -x -a '(cat /etc/group|cut -d : -f 1,3|sed -e "s/:/\n/")' +complete -c useradd -s s -l shell --description 'Name of the new user\'s login shell' -x -a '(cat /etc/shells)' From 8159f55243e79f7107c09047e7d6b9e36f6ababf Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Mon, 2 Sep 2013 20:08:46 +0800 Subject: [PATCH 105/170] git version generation fixes - Remove the `version` file created for the tarball after the tarball is finished - Use the builtin type instead of which. --- build_tools/git_version_gen.sh | 2 +- build_tools/make_tarball.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build_tools/git_version_gen.sh b/build_tools/git_version_gen.sh index 5a54eb3be..3ffd0eb2a 100755 --- a/build_tools/git_version_gen.sh +++ b/build_tools/git_version_gen.sh @@ -12,7 +12,7 @@ DEF_VER=2.0.GIT if test -f version then VN=$(cat version) || VN="$DEF_VER" -elif test -d .git -o -f .git && which git >/dev/null +elif test -d .git -o -f .git && type git >/dev/null then VN=$(git describe --tags --dirty 2>/dev/null) else diff --git a/build_tools/make_tarball.sh b/build_tools/make_tarball.sh index 77d78c67e..54398b131 100755 --- a/build_tools/make_tarball.sh +++ b/build_tools/make_tarball.sh @@ -42,6 +42,7 @@ ln -s "$wd" "$prefix" gnutar --append --file="$path" "$prefix"/user_doc/html gnutar --append --file="$path" "$prefix"/share/man gnutar --append --file="$path" "$prefix"/version +rm -f "$prefix"/version rm -f "$prefix" # gzip it From 04c0ac9ee838bd455d620aa71c5c6642ba973e75 Mon Sep 17 00:00:00 2001 From: Tim Cuthbertson Date: Sat, 24 Aug 2013 18:16:16 +1000 Subject: [PATCH 106/170] add __fish_urlencode function which URL-escapes stdin --- share/functions/__fish_urlencode.fish | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 share/functions/__fish_urlencode.fish diff --git a/share/functions/__fish_urlencode.fish b/share/functions/__fish_urlencode.fish new file mode 100644 index 000000000..ebf5ba5df --- /dev/null +++ b/share/functions/__fish_urlencode.fish @@ -0,0 +1,9 @@ +function __fish_urlencode --description "URL-encode stdin" + while read f + set lines (echo "$f" | sed -E -e 's/./\n\\0/g;/^$/d;s/\n//') + if [ (count $lines) -gt 0 ] + printf '%%%02x' "'"$lines"'" | sed -e 's/%2[fF]/\//g'; + end + end + echo +end From 74e27a0a82d5f074590f825e1e7e8277392efed4 Mon Sep 17 00:00:00 2001 From: Tim Cuthbertson Date: Sat, 24 Aug 2013 18:52:00 +1000 Subject: [PATCH 107/170] Notify vte-based terminals of $PWD change (#906) --- share/functions/__fish_config_interactive.fish | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/share/functions/__fish_config_interactive.fish b/share/functions/__fish_config_interactive.fish index ab1a6837d..458e10d5c 100644 --- a/share/functions/__fish_config_interactive.fish +++ b/share/functions/__fish_config_interactive.fish @@ -213,6 +213,15 @@ function __fish_config_interactive -d "Initializations that should be performed commandline -f repaint end + + # Notify vte-based terminals when $PWD changes (issue #906) + if begin set -q VTE_VERSION; and test $VTE_VERSION -ge 3405; end + function __update_vte_cwd --on-variable PWD --description 'Notify VTE of change to $PWD' + status --is-command-substitution; and return + printf '\033]7;file://%s\a' (pwd | __fish_urlencode) + end + end + # The first time a command is not found, look for command-not-found # This is not cheap so we try to avoid doing it during startup function fish_command_not_found_setup --on-event fish_command_not_found From 6709d1067d1d24b1648fce3b169e98546b68d4dd Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Wed, 4 Sep 2013 20:43:40 +0200 Subject: [PATCH 108/170] Recommend eval when using variable as command. --- parser.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/parser.cpp b/parser.cpp index c80d09cae..c6cbd9b50 100644 --- a/parser.cpp +++ b/parser.cpp @@ -2055,15 +2055,17 @@ int parser_t::parse_job(process_t *p, if (val) { debug(0, - _(L"Variables may not be used as commands. Instead, define a function like 'function %ls; %ls $argv; end'. See the help section for the function command by typing 'help function'."), + _(L"Variables may not be used as commands. Instead, define a function like 'function %ls; %ls $argv; end' or use the eval builtin instead, like 'eval %ls'. See the help section for the function command by typing 'help function'."), cmd+1, val, + cmd, cmd); } else { debug(0, - _(L"Variables may not be used as commands. Instead, define a function. See the help section for the function command by typing 'help function'."), + _(L"Variables may not be used as commands. Instead, define a function or use the eval builtin instead, like 'eval %ls'. See the help section for the function command by typing 'help function'."), + cmd, cmd); } } From fe10f98038aad5d6289426aadbf72f325d508a04 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Wed, 4 Sep 2013 22:08:44 +0200 Subject: [PATCH 109/170] Fix VTE version test --- share/functions/__fish_config_interactive.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/functions/__fish_config_interactive.fish b/share/functions/__fish_config_interactive.fish index 458e10d5c..260e35252 100644 --- a/share/functions/__fish_config_interactive.fish +++ b/share/functions/__fish_config_interactive.fish @@ -215,7 +215,7 @@ function __fish_config_interactive -d "Initializations that should be performed # Notify vte-based terminals when $PWD changes (issue #906) - if begin set -q VTE_VERSION; and test $VTE_VERSION -ge 3405; end + if test "$VTE_VERSION" -ge 3405 function __update_vte_cwd --on-variable PWD --description 'Notify VTE of change to $PWD' status --is-command-substitution; and return printf '\033]7;file://%s\a' (pwd | __fish_urlencode) From 7561075af8a375d6f6c14be0132e9d65ac650aa6 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Thu, 5 Sep 2013 00:46:19 -0700 Subject: [PATCH 110/170] OS X Mavericks keybinding fix --- share/functions/fish_default_key_bindings.fish | 1 + 1 file changed, 1 insertion(+) diff --git a/share/functions/fish_default_key_bindings.fish b/share/functions/fish_default_key_bindings.fish index 26db71d9c..f610e8915 100644 --- a/share/functions/fish_default_key_bindings.fish +++ b/share/functions/fish_default_key_bindings.fish @@ -35,6 +35,7 @@ function fish_default_key_bindings -d "Default (Emacs-like) key bindings for fis # OS X SnowLeopard doesn't have these keys. Don't show an annoying error message. bind -k home beginning-of-line 2> /dev/null bind -k end end-of-line 2> /dev/null + bind \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-delete bind \e\eOC nextd-or-forward-word bind \e\eOD prevd-or-backward-word From 3816abb9def78bca7608401821dd388ad62ccea4 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Thu, 5 Sep 2013 11:40:51 -0700 Subject: [PATCH 111/170] Make __fish_print_mounted work better on OS X --- share/functions/__fish_print_mounted.fish | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/share/functions/__fish_print_mounted.fish b/share/functions/__fish_print_mounted.fish index a7cfc0dec..482559a87 100644 --- a/share/functions/__fish_print_mounted.fish +++ b/share/functions/__fish_print_mounted.fish @@ -1,4 +1,7 @@ function __fish_print_mounted --description 'Print mounted devices' - cat /etc/mtab | cut -d " " -f 1-2|tr " " \n|sed -e "s/[0-9\.]*:\//\//"|sgrep "^/" - + if test (uname) = Darwin + mount | cut -d " " -f 1-2|tr " " \n|sed -e "s/[0-9\.]*:\//\//"|sgrep "^/" + else + cat /etc/mtab | cut -d " " -f 1-2|tr " " \n|sed -e "s/[0-9\.]*:\//\//"|sgrep "^/" + end end From 5ef13d901139498be42c1d2c47606914db2aa490 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Thu, 5 Sep 2013 13:49:18 -0700 Subject: [PATCH 112/170] Remove duplicates from history in fish_config https://github.com/fish-shell/fish-shell/issues/900 --- history.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/history.cpp b/history.cpp index 8e3772d21..f167f6e40 100644 --- a/history.cpp +++ b/history.cpp @@ -629,10 +629,16 @@ void history_t::get_string_representation(wcstring &result, const wcstring &sepa scoped_lock locker(lock); bool first = true; + + std::set seen; /* Append new items. Note that in principle we could use const_reverse_iterator, but we do not because reverse_iterator is not convertible to const_reverse_iterator ( http://github.com/fish-shell/fish-shell/issues/431 ) */ for (std::vector::reverse_iterator iter=new_items.rbegin(); iter < new_items.rend(); ++iter) { + /* Skip duplicates */ + if (! seen.insert(iter->str()).second) + continue; + if (! first) result.append(separator); result.append(iter->str()); @@ -645,6 +651,11 @@ void history_t::get_string_representation(wcstring &result, const wcstring &sepa { size_t offset = *iter; const history_item_t item = history_t::decode_item(mmap_start + offset, mmap_length - offset, mmap_type); + + /* Skip duplicates */ + if (! seen.insert(item.str()).second) + continue; + if (! first) result.append(separator); result.append(item.str()); From 9921e9e79f5f4290e59d88f78a9606775aad577d Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Fri, 6 Sep 2013 10:41:58 +0800 Subject: [PATCH 113/170] document and enforce Autoconf 2.60 or greater --- README.md | 4 +++- configure.ac | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c0b8c69a8..c74624656 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,9 @@ Detailed user documentation is available by running `help` within fish, and also fish is written in a sane subset of C++98, with a few components from C++TR1. It builds successfully with g++ 4.2 or later, and with clang. It also will build as C++11. -fish can be built using autotools or Xcode. +fish can be built using autotools or Xcode. autoconf 2.60 or later is required. + +fish requires gettext for translation support. ### Autotools Build diff --git a/configure.ac b/configure.ac index 1bff836da..21e043afc 100644 --- a/configure.ac +++ b/configure.ac @@ -10,6 +10,7 @@ m4_syscmd([build_tools/git_version_gen.sh 2>/dev/null]) +AC_PREREQ([2.60]) AC_INIT(fish, m4_esyscmd([cut -f 3 -d ' ' FISH-BUILD-VERSION-FILE | tr -d '\n']), fish-users@lists.sf.net) @@ -212,6 +213,7 @@ AS_IF([test "$use_doxygen" != "no"], AC_MSG_CHECKING([the doxygen version]) doxygen_version=`doxygen --version 2>/dev/null` AC_MSG_RESULT([$doxygen_version]) + dnl This requires autoconf 2.60 or newer AS_VERSION_COMPARE([$doxygen_version], [$doxygen_minimum], [ if test "$use_doxygen" = auto; then AC_MSG_WARN([doxygen version $doxygen_version found, but $doxygen_minimum required]) From 5023ade7aca320d5d7ebc031cb93f751734d29e3 Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Fri, 6 Sep 2013 10:43:43 +0800 Subject: [PATCH 114/170] tarball generation should build configure script For the next release, this means that `autoconf` is no longer required if building from the tarball. The website and documentation should be updated accordingly at that time. --- build_tools/make_tarball.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build_tools/make_tarball.sh b/build_tools/make_tarball.sh index 54398b131..3888f4340 100755 --- a/build_tools/make_tarball.sh +++ b/build_tools/make_tarball.sh @@ -32,7 +32,8 @@ rm -f "$path" "$path".gz # git starts the archive git archive --format=tar --prefix="$prefix"/ master > "$path" -# tarball out the documentation +# tarball out the documentation, generate a configure script and version file +autoconf make user_doc make share/man echo $VERSION > version @@ -42,6 +43,7 @@ ln -s "$wd" "$prefix" gnutar --append --file="$path" "$prefix"/user_doc/html gnutar --append --file="$path" "$prefix"/share/man gnutar --append --file="$path" "$prefix"/version +gnutar --append --file="$path" "$prefix"/configure rm -f "$prefix"/version rm -f "$prefix" From 1b1aa07414fc86858666b7b33c7dd6bef69303fa Mon Sep 17 00:00:00 2001 From: Leonardo Boiko Date: Wed, 7 Nov 2012 10:23:04 -0200 Subject: [PATCH 115/170] When exiting, only warn about _stopped_ background jobs (fix #111) --- reader.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/reader.cpp b/reader.cpp index cd9d9e450..c8e28bfa8 100644 --- a/reader.cpp +++ b/reader.cpp @@ -2819,7 +2819,7 @@ int exit_status() static void handle_end_loop() { job_t *j; - int job_count=0; + int stopped_jobs_count=0; int is_breakpoint=0; block_t *b; parser_t &parser = parser_t::principal_parser(); @@ -2838,14 +2838,14 @@ static void handle_end_loop() job_iterator_t jobs; while ((j = jobs.next())) { - if (!job_is_completed(j)) + if (!job_is_completed(j) && (job_is_stopped(j))) { - job_count++; + stopped_jobs_count++; break; } } - if (!reader_exit_forced() && !data->prev_end_loop && job_count && !is_breakpoint) + if (!reader_exit_forced() && !data->prev_end_loop && stopped_jobs_count && !is_breakpoint) { writestr(_(L"There are stopped jobs. A second attempt to exit will enforce their termination.\n")); From a1020b3e6129ddeee8709a757f3275c19a81a0f5 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sun, 8 Sep 2013 20:19:43 +0200 Subject: [PATCH 116/170] Remove useless semicolon in webconfig.py --- share/tools/web_config/webconfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/tools/web_config/webconfig.py b/share/tools/web_config/webconfig.py index 4f07fd9d7..f735a0268 100755 --- a/share/tools/web_config/webconfig.py +++ b/share/tools/web_config/webconfig.py @@ -615,7 +615,7 @@ while PORT <= 9000: Handler = FishConfigHTTPRequestHandler httpd = SocketServer.TCPServer(("", PORT), Handler) # Success - break; + break except socket.error: err_type, err_value = sys.exc_info()[:2] # str(err_value) handles Python3 correctly From cd1c2f74d3bcc9a1d3c5eaad007788e950e27c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Rish=C3=B8j?= Date: Mon, 9 Sep 2013 18:46:16 +0200 Subject: [PATCH 117/170] add support for downcase-word, upcase-word and capitalise-word --- input.cpp | 6 +++ input.h | 3 ++ reader.cpp | 38 ++++++++++++++++++- .../functions/fish_default_key_bindings.fish | 4 ++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/input.cpp b/input.cpp index f3d752a90..b587fcbac 100644 --- a/input.cpp +++ b/input.cpp @@ -115,6 +115,9 @@ static const wchar_t * const name_arr[] = L"self-insert", L"transpose-chars", L"transpose-words", + L"upcase-word", + L"downcase-word", + L"capitalize-word", L"null", L"eof", L"vi-arg-digit", @@ -201,6 +204,9 @@ static const wchar_t code_arr[] = R_SELF_INSERT, R_TRANSPOSE_CHARS, R_TRANSPOSE_WORDS, + R_UPCASE_WORD, + R_DOWNCASE_WORD, + R_CAPITALIZE_WORD, R_NULL, R_EOF, R_VI_ARG_DIGIT, diff --git a/input.h b/input.h index 465d50473..c5722b2fc 100644 --- a/input.h +++ b/input.h @@ -44,6 +44,9 @@ enum R_SELF_INSERT, R_TRANSPOSE_CHARS, R_TRANSPOSE_WORDS, + R_UPCASE_WORD, + R_DOWNCASE_WORD, + R_CAPITALIZE_WORD, R_VI_ARG_DIGIT, R_VI_DELETE_TO, R_EXECUTE, diff --git a/reader.cpp b/reader.cpp index c8e28bfa8..de0b36793 100644 --- a/reader.cpp +++ b/reader.cpp @@ -3790,7 +3790,43 @@ const wchar_t *reader_readline(void) } break; } - + + case R_UPCASE_WORD: + { + size_t pos = data->buff_pos; + move_word(MOVE_DIR_RIGHT, false, move_word_style_punctuation, false); + for (; pos < data->buff_pos; pos++) + data->command_line.at(pos) = towupper(data->command_line.at(pos)); + reader_repaint(); + break; + } + + case R_DOWNCASE_WORD: + { + size_t pos = data->buff_pos; + move_word(MOVE_DIR_RIGHT, false, move_word_style_punctuation, false); + for (; pos < data->buff_pos; pos++) + data->command_line.at(pos) = towlower(data->command_line.at(pos)); + reader_repaint(); + break; + } + + case R_CAPITALIZE_WORD: + { + size_t pos = data->buff_pos; + bool capitalized_first = false; + move_word(MOVE_DIR_RIGHT, false, move_word_style_punctuation, false); + for (; pos < data->buff_pos; pos++) { + if (iswalnum(data->command_line.at(pos)) && !capitalized_first) { + data->command_line.at(pos) = towupper(data->command_line.at(pos)); + capitalized_first = true; + } else + data->command_line.at(pos) = towlower(data->command_line.at(pos)); + } + reader_repaint(); + break; + } + /* Other, if a normal character, we add it to the command */ default: { diff --git a/share/functions/fish_default_key_bindings.fish b/share/functions/fish_default_key_bindings.fish index f610e8915..ff3d6faa9 100644 --- a/share/functions/fish_default_key_bindings.fish +++ b/share/functions/fish_default_key_bindings.fish @@ -70,6 +70,10 @@ function fish_default_key_bindings -d "Default (Emacs-like) key bindings for fis bind \cb backward-char bind \ct transpose-chars bind \et transpose-words + bind \eu upcase-word + # This clashes with __fish_list_current_token + # bind \el downcase-word + bind \ec capitalize-word bind \e\x7f backward-kill-word bind \eb backward-word bind \ef forward-word From b993dce12ff3e5b8e38c761706c9db1ef101aee4 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Tue, 10 Sep 2013 20:46:46 -0700 Subject: [PATCH 118/170] Rework some of the new case-modifying commands to share more code, and also to update the autosuggestion and syntax highlighting --- reader.cpp | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/reader.cpp b/reader.cpp index de0b36793..c3630d73c 100644 --- a/reader.cpp +++ b/reader.cpp @@ -3792,37 +3792,37 @@ const wchar_t *reader_readline(void) } case R_UPCASE_WORD: - { - size_t pos = data->buff_pos; - move_word(MOVE_DIR_RIGHT, false, move_word_style_punctuation, false); - for (; pos < data->buff_pos; pos++) - data->command_line.at(pos) = towupper(data->command_line.at(pos)); - reader_repaint(); - break; - } - case R_DOWNCASE_WORD: - { - size_t pos = data->buff_pos; - move_word(MOVE_DIR_RIGHT, false, move_word_style_punctuation, false); - for (; pos < data->buff_pos; pos++) - data->command_line.at(pos) = towlower(data->command_line.at(pos)); - reader_repaint(); - break; - } - case R_CAPITALIZE_WORD: { - size_t pos = data->buff_pos; + // For capitalize_word, whether we've capitalized a character so far bool capitalized_first = false; + + // We apply the operation from the current location to the end of the word + size_t pos = data->buff_pos; move_word(MOVE_DIR_RIGHT, false, move_word_style_punctuation, false); - for (; pos < data->buff_pos; pos++) { - if (iswalnum(data->command_line.at(pos)) && !capitalized_first) { - data->command_line.at(pos) = towupper(data->command_line.at(pos)); - capitalized_first = true; - } else - data->command_line.at(pos) = towlower(data->command_line.at(pos)); + for (; pos < data->buff_pos; pos++) + { + wchar_t chr = data->command_line.at(pos); + + // We always change the case; this decides whether we go uppercase (true) or lowercase (false) + bool make_uppercase; + if (c == R_CAPITALIZE_WORD) + make_uppercase = ! capitalized_first && iswalnum(chr); + else + make_uppercase = (c == R_UPCASE_WORD); + + // Apply the operation and then record what we did + if (make_uppercase) + chr = towupper(chr); + else + chr = towlower(chr); + + data->command_line.at(pos) = chr; + capitalized_first = capitalized_first || make_uppercase; } + data->command_line_changed(); + reader_super_highlight_me_plenty(data->buff_pos); reader_repaint(); break; } From 61c5b631f3d0050984c938e63525fe8e22fabff2 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Tue, 10 Sep 2013 21:13:47 -0700 Subject: [PATCH 119/170] Fix for infinite loop in cycle_competions, and potential issue in fish_pager when given an empty completion list --- fish_pager.cpp | 5 +++++ reader.cpp | 9 ++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/fish_pager.cpp b/fish_pager.cpp index 848eb0fc0..9cde933e2 100644 --- a/fish_pager.cpp +++ b/fish_pager.cpp @@ -1370,6 +1370,11 @@ int main(int argc, char **argv) // debug( 3, L"prefix is '%ls'", prefix ); + if (comp.empty()) + { + exit_without_destructors(EXIT_FAILURE); + } + init(mangle_descriptors, result_fd); mangle_descriptions(comp); diff --git a/reader.cpp b/reader.cpp index c3630d73c..a1074627d 100644 --- a/reader.cpp +++ b/reader.cpp @@ -1702,18 +1702,17 @@ static const completion_t *cycle_competions(const std::vector &com if (size == 0) return NULL; + // note start_idx will be set to -1 initially, so that when it gets incremented we start at 0 const size_t start_idx = *inout_idx; size_t idx = start_idx; + const completion_t *result = NULL; - for (;;) + size_t remaining = comp.size(); + while (remaining--) { /* Bump the index */ idx = (idx + 1) % size; - /* Bail if we've looped */ - if (idx == start_idx) - break; - /* Get the completion */ const completion_t &c = comp.at(idx); From ee3b355c3445368adf524af79c99244a77e46169 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Wed, 11 Sep 2013 02:33:44 -0700 Subject: [PATCH 120/170] Fix certain wildcard tab completions - https://github.com/fish-shell/fish-shell/issues/929 --- wildcard.cpp | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/wildcard.cpp b/wildcard.cpp index 0edcfa85c..621ece72e 100644 --- a/wildcard.cpp +++ b/wildcard.cpp @@ -227,13 +227,14 @@ static bool wildcard_complete_internal(const wcstring &orig, // Implement EXPAND_FUZZY_MATCH by short-circuiting everything if there are no remaining wildcards if ((expand_flags & EXPAND_FUZZY_MATCH) && ! at_end_of_wildcard && ! wildcard_has(wc, true)) { - fuzzy_match = string_fuzzy_match_string(wc, str); - if (fuzzy_match.type != fuzzy_match_none) + string_fuzzy_match_t local_fuzzy_match = string_fuzzy_match_string(wc, str); + if (local_fuzzy_match.type != fuzzy_match_none) { has_match = true; + fuzzy_match = local_fuzzy_match; /* If we're not a prefix or exact match, then we need to replace the token. Note that in this case we're not going to call ourselves recursively, so these modified flags won't "leak" except into the completion. */ - if (match_type_requires_full_replacement(fuzzy_match.type)) + if (match_type_requires_full_replacement(local_fuzzy_match.type)) { flags |= COMPLETE_REPLACES_TOKEN; completion_string = orig.c_str(); @@ -310,23 +311,38 @@ static bool wildcard_complete_internal(const wcstring &orig, return false; /* Try all submatches */ - do + for (size_t i=0; str[i] != L'\0'; i++) { - res = wildcard_complete_internal(orig, str, wc+1, 0, desc, desc_func, out, expand_flags, flags); - if (res) - break; + const size_t before_count = out.size(); + if (wildcard_complete_internal(orig, str + i, wc+1, false, desc, desc_func, out, expand_flags, flags)) + { + res = true; + + /* #929: if the recursive call gives us a prefix match, just stop. This is sloppy - what we really want to do is say, once we've seen a match of a particular type, ignore all matches of that type further down the string, such that the wildcard produces the "minimal match." */ + bool has_prefix_match = false; + const size_t after_count = out.size(); + for (size_t j = before_count; j < after_count; j++) + { + if (out[j].match.type <= fuzzy_match_prefix) + { + has_prefix_match = true; + break; + } + } + if (has_prefix_match) + break; + } } - while (*str++ != 0); return res; } else if (*wc == ANY_CHAR || *wc == *str) { - return wildcard_complete_internal(orig, str+1, wc+1, 0, desc, desc_func, out, expand_flags, flags); + return wildcard_complete_internal(orig, str+1, wc+1, false, desc, desc_func, out, expand_flags, flags); } else if (towlower(*wc) == towlower(*str)) { - return wildcard_complete_internal(orig, str+1, wc+1, 0, desc, desc_func, out, expand_flags, flags | COMPLETE_REPLACES_TOKEN); + return wildcard_complete_internal(orig, str+1, wc+1, false, desc, desc_func, out, expand_flags, flags | COMPLETE_REPLACES_TOKEN); } return false; } From 46452e7634b658f2a5f704890ae9d77d932d4610 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Wed, 11 Sep 2013 14:22:16 -0700 Subject: [PATCH 121/170] Improve error messages for double square brackets - https://github.com/fish-shell/fish-shell/issues/875 --- parser.cpp | 5 +++-- tokenizer.cpp | 21 +++++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/parser.cpp b/parser.cpp index c6cbd9b50..93e068d78 100644 --- a/parser.cpp +++ b/parser.cpp @@ -3535,8 +3535,8 @@ int parser_t::test(const wchar_t *buff, int *block_level, wcstring *out, const w } else { - err = 1; - if (out) + // Only print errors once + if (out && ! err) { error(SYNTAX_ERROR, tok_get_pos(&tok), @@ -3546,6 +3546,7 @@ int parser_t::test(const wchar_t *buff, int *block_level, wcstring *out, const w print_errors(*out, prefix); } + err = 1; } break; diff --git a/tokenizer.cpp b/tokenizer.cpp index 831197ee5..4521c164d 100644 --- a/tokenizer.cpp +++ b/tokenizer.cpp @@ -36,6 +36,12 @@ segments. */ #define PARAN_ERROR _( L"Unexpected end of string, parenthesis do not match" ) +/** + Error string for mismatched square brackets +*/ +#define SQUARE_BRACKET_ERROR _( L"Unexpected end of string, square brackets do not match" ) + + /** Error string for invalid redirections */ @@ -237,7 +243,6 @@ static void read_string(tokenizer_t *tok) while (1) { - if (!myal(*tok->buff)) { if (*tok->buff == L'\\') @@ -390,7 +395,19 @@ static void read_string(tokenizer_t *tok) if ((!tok->accept_unfinished) && (mode != mode_regular_text)) { - TOK_CALL_ERROR(tok, TOK_UNTERMINATED_SUBSHELL, PARAN_ERROR); + switch (mode) + { + case mode_subshell: + TOK_CALL_ERROR(tok, TOK_UNTERMINATED_SUBSHELL, PARAN_ERROR); + break; + case mode_array_brackets: + case mode_array_brackets_and_subshell: + TOK_CALL_ERROR(tok, TOK_UNTERMINATED_SUBSHELL, SQUARE_BRACKET_ERROR); // TOK_UNTERMINATED_SUBSHELL is a lie but nobody actually looks at it + break; + default: + assert(0 && "Unexpected mode in read_string"); + break; + } return; } From 307a4ae9e854a8697dbde6861839d1c7a0615ef6 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Wed, 11 Sep 2013 18:50:14 -0700 Subject: [PATCH 122/170] Don't do completions or autosuggestions for commands with wildcards. Fixes https://github.com/fish-shell/fish-shell/issues/785 --- expand.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/expand.cpp b/expand.cpp index 9dfe50266..4408a3e4b 100644 --- a/expand.cpp +++ b/expand.cpp @@ -1729,9 +1729,15 @@ int expand_string(const wcstring &input, std::vector &output, expa remove_internal_separator(next_str, (EXPAND_SKIP_WILDCARDS & flags) ? true : false); const wchar_t *next = next_str.c_str(); - - if (((flags & ACCEPT_INCOMPLETE) && (!(flags & EXPAND_SKIP_WILDCARDS))) || - wildcard_has(next, 1)) + + const bool has_wildcard = wildcard_has(next, 1); + + if (has_wildcard && (flags & EXECUTABLES_ONLY)) + { + // Don't do wildcard expansion for executables. See #785. So do nothing here. + } + else if (((flags & ACCEPT_INCOMPLETE) && (!(flags & EXPAND_SKIP_WILDCARDS))) || + has_wildcard) { const wchar_t *start, *rest; From e529f4d75f3a93c1c7497e6a6ac7aa395c75fc45 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Thu, 12 Sep 2013 01:03:41 -0700 Subject: [PATCH 123/170] Fix a comment typo --- complete.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/complete.h b/complete.h index 85208d69a..84b844824 100644 --- a/complete.h +++ b/complete.h @@ -128,7 +128,7 @@ public: completion_t(const completion_t &); completion_t &operator=(const completion_t &); - /* Compare two completions. No operating overlaoding to make this always explicit (there's potentially multiple ways to complare completions). */ + /* Compare two completions. No operating overlaoding to make this always explicit (there's potentially multiple ways to compare completions). */ static bool is_alphabetically_less_than(const completion_t &a, const completion_t &b); static bool is_alphabetically_equal_to(const completion_t &a, const completion_t &b); }; From 1b521d0822fb55ad1ec04b16af7ca39e5becc41a Mon Sep 17 00:00:00 2001 From: nulltrek Date: Thu, 12 Sep 2013 11:02:05 +0200 Subject: [PATCH 124/170] Rename internal functions for consistency. --- share/functions/__fish_config_interactive.fish | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/share/functions/__fish_config_interactive.fish b/share/functions/__fish_config_interactive.fish index 260e35252..d9ee0700e 100644 --- a/share/functions/__fish_config_interactive.fish +++ b/share/functions/__fish_config_interactive.fish @@ -224,26 +224,26 @@ function __fish_config_interactive -d "Initializations that should be performed # The first time a command is not found, look for command-not-found # This is not cheap so we try to avoid doing it during startup - function fish_command_not_found_setup --on-event fish_command_not_found + function __fish_command_not_found_setup --on-event fish_command_not_found # Remove fish_command_not_found_setup so we only execute this once - functions --erase fish_command_not_found_setup + functions --erase __fish_command_not_found_setup # First check in /usr/lib, this is where modern Ubuntus place this command if test -f /usr/lib/command-not-found - function fish_command_not_found_handler --on-event fish_command_not_found + function __fish_command_not_found_handler --on-event fish_command_not_found /usr/lib/command-not-found -- $argv end # Ubuntu Feisty places this command in the regular path instead else if type -p command-not-found > /dev/null 2> /dev/null - function fish_command_not_found_handler --on-event fish_command_not_found + function __fish_command_not_found_handler --on-event fish_command_not_found command-not-found -- $argv end # Use standard fish command not found handler otherwise else - function fish_command_not_found_handler --on-event fish_command_not_found + function __fish_command_not_found_handler --on-event fish_command_not_found echo fish: Unknown command "'$argv'" >&2 end end - fish_command_not_found_handler $argv + __fish_command_not_found_handler $argv end end From e031fa72077140c6b0fa46aa4f8b6c350f75fedc Mon Sep 17 00:00:00 2001 From: nulltrek Date: Thu, 12 Sep 2013 11:06:45 +0200 Subject: [PATCH 125/170] Fix some typos. --- share/functions/__fish_complete_ls.fish | 2 +- share/functions/prompt_pwd.fish | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/share/functions/__fish_complete_ls.fish b/share/functions/__fish_complete_ls.fish index 652a02d37..1fe396599 100644 --- a/share/functions/__fish_complete_ls.fish +++ b/share/functions/__fish_complete_ls.fish @@ -4,7 +4,7 @@ # Test if we are using GNU ls -function __fish_complete_ls -d "Compleletions for ls and its aliases" +function __fish_complete_ls -d "Completions for ls and its aliases" set -l is_gnu command ls --version >/dev/null ^/dev/null; and set is_gnu --is-gnu diff --git a/share/functions/prompt_pwd.fish b/share/functions/prompt_pwd.fish index f559fb046..991b007b7 100644 --- a/share/functions/prompt_pwd.fish +++ b/share/functions/prompt_pwd.fish @@ -1,14 +1,14 @@ switch (uname) case Darwin - function prompt_pwd --description "Print the current working directory, shortend to fit the prompt" + function prompt_pwd --description "Print the current working directory, shortened to fit the prompt" echo $PWD | sed -e "s|^$HOME|~|" -e 's|^/private||' -e 's-\([^/.]\)[^/]*/-\1/-g' end case 'CYGWIN_*' - function prompt_pwd --description "Print the current working directory, shortend to fit the prompt" + function prompt_pwd --description "Print the current working directory, shortened to fit the prompt" echo $PWD | sed -e "s|^$HOME|~|" -e 's|^/cygdrive/\(.\)|\1/:|' -e 's-\([^/.]\)[^/]*/-\1/-g' -e 's-^\([^/]\)/:/\?-\u\1:/-' end case '*' - function prompt_pwd --description "Print the current working directory, shortend to fit the prompt" + function prompt_pwd --description "Print the current working directory, shortened to fit the prompt" echo $PWD | sed -e "s|^$HOME|~|" -e 's-\([^/.]\)[^/]*/-\1/-g' end end From 1442a2abe8ff6924c64c4e7559475c5b58d636f5 Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Mon, 9 Sep 2013 20:01:38 +0800 Subject: [PATCH 126/170] test documentation: update wording, generate test manual page (closes #734) --- build_tools/build_documentation.sh | 4 +--- doc_src/test.txt | 6 ++++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build_tools/build_documentation.sh b/build_tools/build_documentation.sh index 2d971ec2a..76c19a04e 100755 --- a/build_tools/build_documentation.sh +++ b/build_tools/build_documentation.sh @@ -20,10 +20,8 @@ else fi # Determine which man pages we don't want to generate. -# Don't make a test man page. fish's test is conforming, so the system man pages -# are applicable and generally better. # on OS X, don't make a man page for open, since we defeat fish's open function on OS X. -CONDEMNED_PAGES=test.1 +CONDEMNED_PAGES= if test `uname` = 'Darwin'; then CONDEMNED_PAGES="$CONDEMNED_PAGES open.1" fi diff --git a/doc_src/test.txt b/doc_src/test.txt index 035671325..946c53307 100644 --- a/doc_src/test.txt +++ b/doc_src/test.txt @@ -16,9 +16,11 @@ The following operators are available to examine files and directories: - -e FILE returns true if \c FILE exists. - -f FILE returns true if \c FILE is a regular file. - -g FILE returns true if \c FILE has the set-group-ID bit set. -- -G FILE returns true if \c FILE exists and its group matches the effective group id of this process. +- -G FILE returns true if \c FILE exists and has the same group ID +as the current user. - -L FILE returns true if \c FILE is a symbolic link. -- -O FILE returns true if \c FILE exists and its owner matches the effective user id of this process. +- -O FILE returns true if \c FILE exists and is owned by the current +user. - -p FILE returns true if \c FILE is a named pipe. - -r FILE returns true if \c FILE is marked as readable. - -s FILE returns true if the size of \c FILE is greater than zero. From 5b5b53872c5ab99eafd72b4944fb00b5fc93e2d2 Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Mon, 9 Sep 2013 20:08:37 +0800 Subject: [PATCH 127/170] tarball generation: include config.h.in, set mode and ownership Include config.h.in as well as configure. Also sets correct owner, group and mode for all appended files. Update the mtime of all appended files so that configure and config.h.in are always newer than configure.ac. (Fixes many problems introduced by 5023ade7, and makes the commit message actually true.) --- build_tools/make_tarball.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/build_tools/make_tarball.sh b/build_tools/make_tarball.sh index 3888f4340..2c3a0ac1b 100755 --- a/build_tools/make_tarball.sh +++ b/build_tools/make_tarball.sh @@ -33,17 +33,18 @@ rm -f "$path" "$path".gz git archive --format=tar --prefix="$prefix"/ master > "$path" # tarball out the documentation, generate a configure script and version file -autoconf -make user_doc -make share/man +autoreconf +./configure --with-doxygen +make user_doc share/man echo $VERSION > version cd /tmp rm -f "$prefix" ln -s "$wd" "$prefix" -gnutar --append --file="$path" "$prefix"/user_doc/html -gnutar --append --file="$path" "$prefix"/share/man -gnutar --append --file="$path" "$prefix"/version -gnutar --append --file="$path" "$prefix"/configure +TAR_APPEND="gnutar --append --file=$path --mtime=now --owner=root --group=root --mode=g+w,a+rX" +$TAR_APPEND --no-recursion "$prefix"/user_doc +$TAR_APPEND "$prefix"/user_doc/html "$prefix"/share/man +$TAR_APPEND "$prefix"/version +$TAR_APPEND "$prefix"/configure "$prefix"/config.h.in rm -f "$prefix"/version rm -f "$prefix" From b56542a9f195358b1ac33716bde0d731b8e70871 Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Fri, 13 Sep 2013 11:58:31 +0800 Subject: [PATCH 128/170] document new bindings introduced in cd1c2f74d3bc --- doc_src/bind.txt | 3 +++ doc_src/index.hdr.in | 2 ++ 2 files changed, 5 insertions(+) diff --git a/doc_src/bind.txt b/doc_src/bind.txt index d7d17044f..088098784 100644 --- a/doc_src/bind.txt +++ b/doc_src/bind.txt @@ -69,9 +69,11 @@ The following special input functions are available: - \c backward-word, move one word to the left - \c beginning-of-history, move to the beginning of the history - \c beginning-of-line, move to the beginning of the line +- \c capitalize-word, make the current word begin with a capital letter - \c complete, guess the remainder of the current token - \c delete-char, delete one character to the right of the cursor - \c delete-line, delete the entire line +- \c downcase-word, make the current work lowercase - \c dump-functions, print a list of all key-bindings - \c end-of-history, move to the end of the history - \c end-of-line, move to the end of the line @@ -83,6 +85,7 @@ The following special input functions are available: - \c kill-line, move everything from the cursor to the end of the line to the killring - \c kill-whole-line, move the line to the killring - \c kill-word, move the next word to the killring +- \c upcase-word, make the current word uppercase - \c yank, insert the latest entry of the killring into the buffer - \c yank-pop, rotate to the previous entry of the killring diff --git a/doc_src/index.hdr.in b/doc_src/index.hdr.in index 26fc56967..1347b37d8 100644 --- a/doc_src/index.hdr.in +++ b/doc_src/index.hdr.in @@ -1120,6 +1120,8 @@ Here are some of the commands available in the editor: - Alt-W prints a short description of the command under the cursor. - Alt-L lists the contents of the current directory, unless the cursor is over a directory argument, in which case the contents of that directory will be listed. - Alt-P adds the string '| less;' to the end of the job under the cursor. The result is that the output of the command will be paged. +- Alt-C capitalizes the current word. +- Alt-U makes the current work uppercase. You can change these key bindings using the bind builtin command. From 1565f9d9c3bf5957edf7cb2665f978b34a0c6054 Mon Sep 17 00:00:00 2001 From: "David Adam (zanchey)" Date: Fri, 13 Sep 2013 13:43:36 +0800 Subject: [PATCH 129/170] fix typo introduced in b56542a9f Thanks to @siteshwar for spotting. https://github.com/fish-shell/fish-shell/commit/b56542a9f195358b1ac33716bde0d731b8e70871#commitcomment-4083982 https://github.com/fish-shell/fish-shell/commit/b56542a9f195358b1ac33716bde0d731b8e70871#commitcomment-4083982 --- doc_src/bind.txt | 2 +- doc_src/index.hdr.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc_src/bind.txt b/doc_src/bind.txt index 088098784..8c7004d0d 100644 --- a/doc_src/bind.txt +++ b/doc_src/bind.txt @@ -73,7 +73,7 @@ The following special input functions are available: - \c complete, guess the remainder of the current token - \c delete-char, delete one character to the right of the cursor - \c delete-line, delete the entire line -- \c downcase-word, make the current work lowercase +- \c downcase-word, make the current word lowercase - \c dump-functions, print a list of all key-bindings - \c end-of-history, move to the end of the history - \c end-of-line, move to the end of the line diff --git a/doc_src/index.hdr.in b/doc_src/index.hdr.in index 1347b37d8..5886340de 100644 --- a/doc_src/index.hdr.in +++ b/doc_src/index.hdr.in @@ -1121,7 +1121,7 @@ Here are some of the commands available in the editor: - Alt-L lists the contents of the current directory, unless the cursor is over a directory argument, in which case the contents of that directory will be listed. - Alt-P adds the string '| less;' to the end of the job under the cursor. The result is that the output of the command will be paged. - Alt-C capitalizes the current word. -- Alt-U makes the current work uppercase. +- Alt-U makes the current word uppercase. You can change these key bindings using the bind builtin command. From daf3469ce4eab8f772b03944dcf788c4608d0ca2 Mon Sep 17 00:00:00 2001 From: nulltrek Date: Thu, 12 Sep 2013 12:10:24 +0200 Subject: [PATCH 130/170] Add newline before listing current token. --- share/functions/__fish_list_current_token.fish | 1 + 1 file changed, 1 insertion(+) diff --git a/share/functions/__fish_list_current_token.fish b/share/functions/__fish_list_current_token.fish index 878ac9d1b..a88978cc3 100644 --- a/share/functions/__fish_list_current_token.fish +++ b/share/functions/__fish_list_current_token.fish @@ -6,6 +6,7 @@ function __fish_list_current_token -d "List contents of token under the cursor if it is a directory, otherwise list the contents of the current directory" set val (eval echo (commandline -t)) + printf "\n" if test -d $val ls $val else From 95d5e55df25962282b3a9522400db0f4f227b413 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 14 Sep 2013 23:59:53 -0700 Subject: [PATCH 131/170] Don't do fuzzy matching for file completions for arguments beginning with a dash, as suggested in #568 --- complete.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/complete.cpp b/complete.cpp index ad2bbb143..7b0b41735 100644 --- a/complete.cpp +++ b/complete.cpp @@ -1616,7 +1616,7 @@ void completer_t::complete_param_expand(const wcstring &sstr, bool do_file) comp_str = str; } - expand_flags_t flags = EXPAND_SKIP_CMDSUBST | ACCEPT_INCOMPLETE; + expand_flags_t flags = EXPAND_SKIP_CMDSUBST | ACCEPT_INCOMPLETE | this->expand_flags(); if (! do_file) flags |= EXPAND_SKIP_WILDCARDS; @@ -1625,9 +1625,13 @@ void completer_t::complete_param_expand(const wcstring &sstr, bool do_file) if (this->type() == COMPLETE_AUTOSUGGEST || do_file) flags |= EXPAND_NO_DESCRIPTIONS; + /* Don't do fuzzy matching for files if the string begins with a dash (#568). We could consider relaxing this if there was a preceding double-dash argument */ + if (string_prefixes_string(L"-", sstr)) + flags &= ~EXPAND_FUZZY_MATCH; + if (expand_string(comp_str, this->completions, - flags | this->expand_flags()) == EXPAND_ERROR) + flags ) == EXPAND_ERROR) { debug(3, L"Error while expanding string '%ls'", comp_str); } From 8df81f93c8556356ebae7139de4edca322e53ac5 Mon Sep 17 00:00:00 2001 From: David Adam Date: Tue, 17 Sep 2013 22:20:16 +0800 Subject: [PATCH 132/170] __fish_print_packages: whitespace fix --- share/functions/__fish_print_packages.fish | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/share/functions/__fish_print_packages.fish b/share/functions/__fish_print_packages.fish index 95a822c7b..96d1a6ed8 100644 --- a/share/functions/__fish_print_packages.fish +++ b/share/functions/__fish_print_packages.fish @@ -2,7 +2,7 @@ function __fish_print_packages # apt-cache is much, much faster than rpm, and can do this in real - # time. We use it if available. + # time. We use it if available. switch (commandline -tc) case '-**' @@ -22,18 +22,18 @@ function __fish_print_packages return end - # Pkg is fast on FreeBSD and provides versioning info which we want for - # installed packages - if begin - type -f pkg > /dev/null - and test (uname) = "FreeBSD" - end - pkg query "%n-%v" - return - end + # Pkg is fast on FreeBSD and provides versioning info which we want for + # installed packages + if begin + type -f pkg > /dev/null + and test (uname) = "FreeBSD" + end + pkg query "%n-%v" + return + end - # yum is slow, just like rpm, so go to the background + # yum is slow, just like rpm, so go to the background if type -f /usr/share/yum-cli/completion-helper.py >/dev/null # If the cache is less than six hours old, we do not recalculate it @@ -49,11 +49,11 @@ function __fish_print_packages end # Remove package version information from output and pipe into cache file - /usr/share/yum-cli/completion-helper.py list all -d 0 -C >$cache_file | cut -d '.' -f 1 | sed '1d' | sed '/^\s/d' | sed -e 's/$/'\t$package'/' & + /usr/share/yum-cli/completion-helper.py list all -d 0 -C >$cache_file | cut -d '.' -f 1 | sed '1d' | sed '/^\s/d' | sed -e 's/$/'\t$package'/' & end # Rpm is too slow for this job, so we set it up to do completions - # as a background job and cache the results. + # as a background job and cache the results. if type -f rpm >/dev/null From 7935b1613a105303288d037811c2bea5a5468822 Mon Sep 17 00:00:00 2001 From: David Adam Date: Tue, 17 Sep 2013 22:27:15 +0800 Subject: [PATCH 133/170] __fish_print_packages: ignore errors, do less manipulation Closes #479 by piping STDERR to /dev/null. Also does much less manipulation of the package list; there are no packages in any of the archives containing the names that are stripped out as far as I can see. --- share/functions/__fish_print_packages.fish | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/share/functions/__fish_print_packages.fish b/share/functions/__fish_print_packages.fish index 96d1a6ed8..decf410df 100644 --- a/share/functions/__fish_print_packages.fish +++ b/share/functions/__fish_print_packages.fish @@ -13,12 +13,9 @@ function __fish_print_packages set -l package (_ Package) if type -f apt-cache >/dev/null - # Apply the following filters to output of apt-cache: - # 1) Remove package names with parentesis in them, since these seem to not correspond to actual packages as reported by rpm - # 2) Remove package names that are .so files, since these seem to not correspond to actual packages as reported by rpm - # 3) Remove path information such as /usr/bin/, as rpm packages do not have paths - - apt-cache --no-generate pkgnames (commandline -tc)|sgrep -v \( |sgrep -v '\.so\(\.[0-9]\)*$'|sed -e 's/\/.*\///'|sed -e 's/$/'\t$package'/' + # Do not generate the cache as apparently sometimes this is slow. + # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=547550 + apt-cache --no-generate pkgnames (commandline -tc) ^/dev/null | sed -e 's/$/'\t$package'/' return end From 3996f178e5c8c77e02a3a821d9367bd74f1a61ed Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Wed, 18 Sep 2013 14:54:11 +0200 Subject: [PATCH 134/170] Added git stash completion options. Squashed commit of the following: commit 962a19dfab7f04552ce7919fff91e945bab53bde Author: Mandeep Sandhu Date: Wed Sep 18 18:09:49 2013 +0530 Add missing 'git stash' completion options Fixed typo. commit 57bbd89caf922228363418cacbfa1daeb352e520 Author: Mandeep Sandhu Date: Wed Sep 18 17:59:36 2013 +0530 Add missing 'git stash' completion options Added the following options which were missing: * save * branch --- share/completions/git.fish | 2 ++ 1 file changed, 2 insertions(+) diff --git a/share/completions/git.fish b/share/completions/git.fish index 3532ef652..138b2c4a5 100644 --- a/share/completions/git.fish +++ b/share/completions/git.fish @@ -328,6 +328,8 @@ complete -f -c git -n '__fish_git_using_command stash' -a apply -d 'Apply a sing complete -f -c git -n '__fish_git_using_command stash' -a clear -d 'Remove all stashed states' complete -f -c git -n '__fish_git_using_command stash' -a drop -d 'Remove a single stashed state from the stash list' complete -f -c git -n '__fish_git_using_command stash' -a create -d 'Create a stash' +complete -f -c git -n '__fish_git_using_command stash' -a save -d 'Save a new stash' +complete -f -c git -n '__fish_git_using_command stash' -a branch -d 'Create a new branch from a stash' # TODO other options ### config From df300e042b12cc045669f39a9b2c6f7296f0d2f9 Mon Sep 17 00:00:00 2001 From: bathtub Date: Wed, 18 Sep 2013 13:32:41 -0700 Subject: [PATCH 135/170] Small fix for fish_update_completions (amended) Amended from https://github.com/fish-shell/fish-shell/pull/1003. Fix a Unicode parsing error; search man6. --- share/tools/create_manpage_completions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/tools/create_manpage_completions.py b/share/tools/create_manpage_completions.py index 8bf41e42c..14bf13ee7 100755 --- a/share/tools/create_manpage_completions.py +++ b/share/tools/create_manpage_completions.py @@ -572,7 +572,7 @@ class TypeDarwinManParser(ManParser): # Extract the description desc_lines = [] while lines and not self.is_option(lines[0]): - line = lines.pop(0).strip() + line = lossy_unicode(lines.pop(0).strip()) if line.startswith('.'): line = self.groff_replace_escapes(line) line = self.trim_groff(line).strip() @@ -871,7 +871,7 @@ def get_paths_from_manpath(): sys.exit(-1) result = [] for parent_path in parent_paths: - for section in ['man1', 'man8']: + for section in ['man1', 'man6', 'man8']: directory_path = os.path.join(parent_path, section) try: names = os.listdir(directory_path) From c2dcfc917635593f34b590dd3b53ae7866e9dfa3 Mon Sep 17 00:00:00 2001 From: David Adam Date: Thu, 19 Sep 2013 23:18:35 +0800 Subject: [PATCH 136/170] __fish_print_hostnames: do a better job of searching SSH files --- share/functions/__fish_print_hostnames.fish | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/share/functions/__fish_print_hostnames.fish b/share/functions/__fish_print_hostnames.fish index 423f9952d..2c737a69a 100644 --- a/share/functions/__fish_print_hostnames.fish +++ b/share/functions/__fish_print_hostnames.fish @@ -13,11 +13,13 @@ function __fish_print_hostnames -d "Print a list of known hostnames" end # Print hosts with known ssh keys - cat ~/.ssh/known_hosts{,2} ^/dev/null | grep -v '^|' | cut -d ' ' -f 1| cut -d , -f 1 + # Does not match hostnames with @directives specified + sgrep -Eoh '^[^#@|, ]*' ~/.ssh/known_hosts{,2} ^/dev/null # Print hosts from ssh configuration file if [ -e ~/.ssh/config ] - sgrep -i '^ *host' ~/.ssh/config | grep -v '[*?]' | cut -d ' ' -f 2 + # Ignore lines containing wildcards + sgrep -Eoi '^ *host[^*]*$' ~/.ssh/config | cut -d '=' -f 2 | tr ' ' '\n' end end From 3d68d1bbe2863c67d64b89fda0dbe302e7caa90f Mon Sep 17 00:00:00 2001 From: David Adam Date: Thu, 19 Sep 2013 23:19:13 +0800 Subject: [PATCH 137/170] scp completions: use __fish_print_hostnames rather than doing independent hostname searches --- share/completions/scp.fish | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/share/completions/scp.fish b/share/completions/scp.fish index 104cf5211..f7e131f50 100644 --- a/share/completions/scp.fish +++ b/share/completions/scp.fish @@ -10,17 +10,12 @@ __fish_complete_ssh scp complete -c scp -d Hostname -a " -( - #Find a suitable hostname from the knownhosts files - cat ~/.ssh/known_hosts{,2} ^/dev/null|cut -d ' ' -f 1| cut -d , -f 1 -): +(__fish_print_hostnames): ( #Prepend any username specified in the completion to the hostname commandline -ct |sed -ne 's/\(.*@\).*/\1/p' -)( - cat ~/.ssh/known_hosts{,2} ^/dev/null|cut -d ' ' -f 1| cut -d , -f 1 -): +)(__fish_print_hostnames): (__fish_print_users)@\tUsername From fdef82f89c744a219e0d2d524b3234fbc23b8fe7 Mon Sep 17 00:00:00 2001 From: David Adam Date: Thu, 19 Sep 2013 23:24:07 +0800 Subject: [PATCH 138/170] rsync completions: complete hostnames ala scp Closes #1010 --- share/completions/rsync.fish | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/share/completions/rsync.fish b/share/completions/rsync.fish index 5a758175a..f749aaa55 100644 --- a/share/completions/rsync.fish +++ b/share/completions/rsync.fish @@ -104,6 +104,22 @@ complete -c rsync -s 6 -l ipv6 --description "Prefer IPv6" complete -c rsync -l version --description "Display version and exit" complete -c rsync -l help --description "Display help and exit" +# +# Hostname completion +# +complete -c rsync -d Hostname -a " + +(__fish_print_hostnames): + +( + #Prepend any username specified in the completion to the hostname + commandline -ct |sed -ne 's/\(.*@\).*/\1/p' +)(__fish_print_hostnames): + +(__fish_print_users)@\tUsername + +" + # # Remote path # From 73f1030bdeac8a92d7dc8e0d317ff11960cf9fa4 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 21 Sep 2013 15:15:06 -0700 Subject: [PATCH 139/170] Fix set_color crash on 'ignore' and 'reset' https://github.com/fish-shell/fish-shell/issues/996 --- builtin_set_color.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/builtin_set_color.cpp b/builtin_set_color.cpp index 14cf84ca0..6e8f55b0a 100644 --- a/builtin_set_color.cpp +++ b/builtin_set_color.cpp @@ -152,14 +152,14 @@ static int builtin_set_color(parser_t &parser, wchar_t **argv) } const rgb_color_t fg = rgb_color_t(fgcolor ? fgcolor : L""); - if (fgcolor && fg.is_none()) + if (fgcolor && (fg.is_none() || fg.is_ignore())) { append_format(stderr_buffer, _(L"%ls: Unknown color '%ls'\n"), argv[0], fgcolor); return STATUS_BUILTIN_ERROR; } const rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : L""); - if (bgcolor && bg.is_none()) + if (bgcolor && (bg.is_none() || bg.is_ignore())) { append_format(stderr_buffer, _(L"%ls: Unknown color '%ls'\n"), argv[0], bgcolor); return STATUS_BUILTIN_ERROR; @@ -212,7 +212,7 @@ static int builtin_set_color(parser_t &parser, wchar_t **argv) if (fgcolor != NULL) { - if (fg.is_normal()) + if (fg.is_normal() || fg.is_reset()) { write_foreground_color(0); writembs(tparm(exit_attribute_mode)); @@ -225,7 +225,7 @@ static int builtin_set_color(parser_t &parser, wchar_t **argv) if (bgcolor != NULL) { - if (! bg.is_normal()) + if (! bg.is_normal() && ! bg.is_reset()) { write_background_color(index_for_color(bg)); } From 44bd405ed3c33e6002bdefc83153c94031d3376e Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 21 Sep 2013 16:27:37 -0700 Subject: [PATCH 140/170] reader_replace_current_token can be made static --- reader.cpp | 2 +- reader.h | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/reader.cpp b/reader.cpp index a1074627d..94074b7f4 100644 --- a/reader.cpp +++ b/reader.cpp @@ -2162,7 +2162,7 @@ static void set_command_line_and_position(const wcstring &new_str, size_t pos) reader_repaint(); } -void reader_replace_current_token(const wchar_t *new_token) +static void reader_replace_current_token(const wchar_t *new_token) { const wchar_t *begin, *end; diff --git a/reader.h b/reader.h index 0ead2aa40..28340ad7a 100644 --- a/reader.h +++ b/reader.h @@ -216,11 +216,6 @@ void reader_set_exit_on_interrupt(bool flag); */ int exit_status(); -/** - Replace the current token with the specified string -*/ -void reader_replace_current_token(const wchar_t *new_token); - /** The readers interrupt signal handler. Cancels all currently running blocks. */ From 97ea61a407a1f0987edc09a0ea176413ec3898e4 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 21 Sep 2013 16:38:57 -0700 Subject: [PATCH 141/170] Fix for parse_util_token_extent doing the wrong thing inside a command substitution. Fixes https://github.com/fish-shell/fish-shell/issues/833 --- parse_util.cpp | 35 +++++++++++++++++------------------ reader.cpp | 2 +- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/parse_util.cpp b/parse_util.cpp index 5e6f4459b..dca23d3ef 100644 --- a/parse_util.cpp +++ b/parse_util.cpp @@ -411,35 +411,34 @@ void parse_util_token_extent(const wchar_t *buff, const wchar_t **prev_begin, const wchar_t **prev_end) { - const wchar_t *begin, *end; - long pos; - const wchar_t *a = NULL, *b = NULL, *pa = NULL, *pb = NULL; CHECK(buff,); assert(cursor_pos >= 0); - parse_util_cmdsubst_extent(buff, cursor_pos, &begin, &end); + const wchar_t *cmdsubst_begin, *cmdsubst_end; + parse_util_cmdsubst_extent(buff, cursor_pos, &cmdsubst_begin, &cmdsubst_end); - if (!end || !begin) + if (!cmdsubst_end || !cmdsubst_begin) { return; } - pos = cursor_pos - (begin - buff); + /* pos is equivalent to cursor_pos within the range of the command substitution {begin, end} */ + long offset_within_cmdsubst = cursor_pos - (cmdsubst_begin - buff); - a = buff + pos; + a = cmdsubst_begin + offset_within_cmdsubst; b = a; - pa = buff + pos; + pa = cmdsubst_begin + offset_within_cmdsubst; pb = pa; - assert(begin >= buff); - assert(begin <= (buff+wcslen(buff))); - assert(end >= begin); - assert(end <= (buff+wcslen(buff))); + assert(cmdsubst_begin >= buff); + assert(cmdsubst_begin <= (buff+wcslen(buff))); + assert(cmdsubst_end >= cmdsubst_begin); + assert(cmdsubst_end <= (buff+wcslen(buff))); - const wcstring buffcpy = wcstring(begin, end-begin); + const wcstring buffcpy = wcstring(cmdsubst_begin, cmdsubst_end-cmdsubst_begin); tokenizer_t tok(buffcpy.c_str(), TOK_ACCEPT_UNFINISHED | TOK_SQUASH_ERRORS); for (; tok_has_next(&tok); tok_next(&tok)) @@ -460,9 +459,9 @@ void parse_util_token_extent(const wchar_t *buff, cursor is between two tokens, so we set it to a zero element string and break */ - if (tok_begin > pos) + if (tok_begin > offset_within_cmdsubst) { - a = b = (wchar_t *)buff + pos; + a = b = cmdsubst_begin + offset_within_cmdsubst; break; } @@ -470,9 +469,9 @@ void parse_util_token_extent(const wchar_t *buff, If cursor is inside the token, this is the token we are looking for. If so, set a and b and break */ - if ((tok_last_type(&tok) == TOK_STRING) && (tok_end >= pos)) + if ((tok_last_type(&tok) == TOK_STRING) && (tok_end >= offset_within_cmdsubst)) { - a = begin + tok_get_pos(&tok); + a = cmdsubst_begin + tok_get_pos(&tok); b = a + wcslen(tok_last(&tok)); break; } @@ -482,7 +481,7 @@ void parse_util_token_extent(const wchar_t *buff, */ if (tok_last_type(&tok) == TOK_STRING) { - pa = begin + tok_get_pos(&tok); + pa = cmdsubst_begin + tok_get_pos(&tok); pb = pa + wcslen(tok_last(&tok)); } } diff --git a/reader.cpp b/reader.cpp index 94074b7f4..cf5427012 100644 --- a/reader.cpp +++ b/reader.cpp @@ -2170,7 +2170,7 @@ static void reader_replace_current_token(const wchar_t *new_token) /* Find current token */ const wchar_t *buff = data->command_line.c_str(); - parse_util_token_extent((wchar_t *)buff, data->buff_pos, &begin, &end, 0, 0); + parse_util_token_extent(buff, data->buff_pos, &begin, &end, 0, 0); if (!begin || !end) return; From 061b872498a7a8dbce4798dd1900929f4c0ea505 Mon Sep 17 00:00:00 2001 From: Alex Charron Date: Thu, 19 Sep 2013 17:20:05 -0400 Subject: [PATCH 142/170] Refactored builtin_echo with better argument parsing. --- builtin.cpp | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/builtin.cpp b/builtin.cpp index d01322e21..57a5708cc 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -1598,30 +1598,43 @@ static int builtin_echo(parser_t &parser, wchar_t **argv) bool print_newline = true, print_spaces = true, interpret_special_chars = false; while (*argv) { - if (! wcscmp(*argv, L"-n")) + wchar_t *s = *argv, c = *s; + if (c == L'-') { - print_newline = false; - } - else if (! wcscmp(*argv, L"-e")) - { - interpret_special_chars = true; - } - else if (! wcscmp(*argv, L"-ne")) - { - print_newline = false; - interpret_special_chars = true; - } - else if (! wcscmp(*argv, L"-s")) - { - // fish-specific extension, which we should try to nix - print_spaces = false; - } - else if (! wcscmp(*argv, L"-E")) - { - interpret_special_chars = false; + /* Ensure that option is valid */ + for (++s, c = *s; c != L'\0'; c = *(++s)) + { + if (c != L'n' && c != L'e' && c != L's' && c != L'E') + { + goto invalid_echo_option; + } + } + + /* Parse option */ + for (s = *argv, ++s, c = *s; c != L'\0'; c = *(++s)) + { + switch (c) + { + case L'n': + print_newline = false; + break; + case L'e': + interpret_special_chars = true; + break; + case L's': + // fish-specific extension, + // which we should try to nix + print_spaces = false; + break; + case L'E': + interpret_special_chars = false; + break; + } + } } else { + invalid_echo_option: break; } argv++; From a7ed3658e33395e8ae1223a295a761bd98fd96ee Mon Sep 17 00:00:00 2001 From: David Adam Date: Sun, 22 Sep 2013 14:28:10 +0800 Subject: [PATCH 143/170] Update to latest config.sub and config.guess versions (Now from Automake 1.11.6.) --- config.guess | 570 +++++++++++++++++++++++++++------------------------ config.sub | 337 ++++++++++++++++++++++-------- 2 files changed, 556 insertions(+), 351 deletions(-) diff --git a/config.guess b/config.guess index ec46d18ca..d622a44e5 100755 --- a/config.guess +++ b/config.guess @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, -# Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. -timestamp='2006-02-27' +timestamp='2012-02-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -17,9 +17,7 @@ timestamp='2006-02-27' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -27,16 +25,16 @@ timestamp='2006-02-27' # the same distribution terms that you use for the rest of that program. -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` @@ -56,7 +54,8 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO @@ -144,7 +143,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward @@ -161,6 +160,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched @@ -169,7 +169,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null + | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? @@ -179,7 +179,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in fi ;; *) - os=netbsd + os=netbsd ;; esac # The OS release @@ -211,7 +211,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) - echo powerppc-unknown-mirbsd${UNAME_RELEASE} + echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} @@ -222,7 +222,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on @@ -268,7 +268,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead @@ -294,7 +297,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo s390-ibm-zvmoe exit ;; *:OS400:*:*) - echo powerpc-ibm-os400 + echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} @@ -323,14 +326,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize @@ -374,23 +396,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; @@ -460,8 +482,8 @@ EOF echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ @@ -474,7 +496,7 @@ EOF else echo i586-dg-dgux${UNAME_RELEASE} fi - exit ;; + exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; @@ -531,7 +553,7 @@ EOF echo rs6000-ibm-aix3.2 fi exit ;; - *:AIX:*:[45]) + *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 @@ -574,52 +596,52 @@ EOF 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac + esac ;; + esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + sed 's/^ //' << EOF >$dummy.c - #define _HPUX_SOURCE - #include - #include + #define _HPUX_SOURCE + #include + #include - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa @@ -639,7 +661,7 @@ EOF # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null + grep -q __LP64__ then HP_ARCH="hppa2.0w" else @@ -710,22 +732,22 @@ EOF exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd - exit ;; + exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit ;; + exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd - exit ;; + exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd - exit ;; + exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd - exit ;; + exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; @@ -749,14 +771,14 @@ EOF exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} @@ -768,38 +790,48 @@ EOF echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; - i*:MINGW*:*) + *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; - i*:MSYS_NT-*:*:*) - echo ${UNAME_MACHINE}-pc-mingw32 + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; - x86:Interix*:[345]*) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - EM64T:Interix*:[345]*) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we @@ -829,82 +861,13 @@ EOF i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; - arm*:Linux:*:*) + aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; @@ -914,11 +877,90 @@ EOF EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in @@ -927,14 +969,17 @@ EOF *) echo hppa-unknown-linux-gnu ;; esac exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu @@ -942,75 +987,18 @@ EOF sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun) - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^LIBC/{ - s: ::g - p - }'`" - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both @@ -1018,11 +1006,11 @@ EOF echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. + # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) @@ -1039,7 +1027,7 @@ EOF i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) @@ -1054,7 +1042,7 @@ EOF fi exit ;; i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. + # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; @@ -1082,10 +1070,13 @@ EOF exit ;; pc:*:*:*) # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit ;; + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; @@ -1120,8 +1111,18 @@ EOF /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; @@ -1134,7 +1135,7 @@ EOF rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) @@ -1154,10 +1155,10 @@ EOF echo ns32k-sni-sysv fi exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm @@ -1183,11 +1184,11 @@ EOF exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv${UNAME_RELEASE} else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv${UNAME_RELEASE} fi - exit ;; + exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; @@ -1197,6 +1198,9 @@ EOF BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; @@ -1206,6 +1210,15 @@ EOF SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; @@ -1215,6 +1228,16 @@ EOF *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} @@ -1230,6 +1253,9 @@ EOF *:QNX:*:4*) echo i386-pc-qnx exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; @@ -1275,13 +1301,13 @@ EOF echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` + UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; @@ -1296,6 +1322,12 @@ EOF i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 @@ -1318,11 +1350,11 @@ main () #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 - "4" + "4" #else - "" + "" #endif - ); exit (0); + ); exit (0); #endif #endif @@ -1456,9 +1488,9 @@ This script, last modified $timestamp, has failed to recognize the operating system you are using. It is advised that you download the most up to date version of the config scripts from - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD and - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD If the version you run ($0) is already up to date, please send the following data and any information you think might be diff --git a/config.sub b/config.sub index ab2c16c0b..6205f8423 100755 --- a/config.sub +++ b/config.sub @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, -# Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. -timestamp='2006-02-27' +timestamp='2012-04-18' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -21,9 +21,7 @@ timestamp='2006-02-27' # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -32,13 +30,16 @@ timestamp='2006-02-27' # Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. +# diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. @@ -72,7 +73,8 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO @@ -120,12 +122,18 @@ esac # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ - uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] @@ -148,10 +156,13 @@ case $os in -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) + -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; + -bluegene*) + os=-cnk + ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 @@ -166,10 +177,10 @@ case $os in os=-chorusos basic_machine=$1 ;; - -chorusrdb) - os=-chorusrdb + -chorusrdb) + os=-chorusrdb basic_machine=$1 - ;; + ;; -hiux*) os=-hiuxwe2 ;; @@ -214,6 +225,12 @@ case $os in -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; -lynx*) os=-lynxos ;; @@ -238,23 +255,32 @@ case $basic_machine in # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ + | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ + | epiphany \ + | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ - | mips64vr | mips64vrel \ + | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ @@ -267,31 +293,42 @@ case $basic_machine in | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ + | moxie \ | mt \ | msp430 \ + | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ + | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ - | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k) + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) basic_machine=$basic_machine-unknown ;; - m32c) - basic_machine=$basic_machine-unknown + c54x) + basic_machine=tic54x-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; @@ -301,6 +338,21 @@ case $basic_machine in basic_machine=mt-unknown ;; + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. @@ -315,29 +367,36 @@ case $basic_machine in # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ + | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ - | m32r-* | m32rle-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ + | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ @@ -352,29 +411,36 @@ case $basic_machine in | mmix-* \ | mt-* \ | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ | tron-* \ - | v850-* | v850e-* | vax-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ | ymp-* \ - | z8k-*) + | z8k-* | z80-*) ;; - m32c-*) + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. @@ -392,7 +458,7 @@ case $basic_machine in basic_machine=a29k-amd os=-udi ;; - abacus) + abacus) basic_machine=abacus-unknown ;; adobe68k) @@ -438,6 +504,10 @@ case $basic_machine in basic_machine=m68k-apollo os=-bsd ;; + aros) + basic_machine=i386-pc + os=-aros + ;; aux) basic_machine=m68k-apple os=-aux @@ -446,10 +516,35 @@ case $basic_machine in basic_machine=ns32k-sequent os=-dynix ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; c90) basic_machine=c90-cray os=-unicos ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; convex-c1) basic_machine=c1-convex os=-bsd @@ -478,8 +573,8 @@ case $basic_machine in basic_machine=craynv-cray os=-unicosmp ;; - cr16c) - basic_machine=cr16c-unknown + cr16 | cr16-*) + basic_machine=cr16-unknown os=-elf ;; crds | unos) @@ -517,6 +612,10 @@ case $basic_machine in basic_machine=m88k-motorola os=-sysv3 ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp @@ -632,7 +731,6 @@ case $basic_machine in i370-ibm* | ibm*) basic_machine=i370-ibm ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 @@ -671,6 +769,14 @@ case $basic_machine in basic_machine=m68k-isi os=-sysv ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; m88k-omron*) basic_machine=m88k-omron ;; @@ -682,10 +788,17 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; + microblaze) + basic_machine=microblaze-xilinx + ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; miniframe) basic_machine=m68000-convergent ;; @@ -714,10 +827,18 @@ case $basic_machine in ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; + msys) + basic_machine=i386-pc + os=-msys + ;; mvs) basic_machine=i370-ibm os=-mvs ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 @@ -782,6 +903,12 @@ case $basic_machine in np1) basic_machine=np1-gould ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; nsr-tandem) basic_machine=nsr-tandem ;; @@ -812,6 +939,14 @@ case $basic_machine in basic_machine=i860-intel os=-osf ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; pbd) basic_machine=sparc-tti ;; @@ -856,9 +991,10 @@ case $basic_machine in ;; power) basic_machine=power-ibm ;; - ppc) basic_machine=powerpc-unknown + ppc | ppcbe) basic_machine=powerpc-unknown ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown @@ -913,6 +1049,10 @@ case $basic_machine in sb1el) basic_machine=mipsisa64sb1el-unknown ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; sei) basic_machine=mips-sei os=-seiux @@ -924,6 +1064,9 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; + sh5el) + basic_machine=sh5le-unknown + ;; sh64) basic_machine=sh64-unknown ;; @@ -945,6 +1088,9 @@ case $basic_machine in basic_machine=i860-stratus os=-sysv4 ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; sun2) basic_machine=m68000-sun ;; @@ -1001,17 +1147,9 @@ case $basic_machine in basic_machine=t90-cray os=-unicos ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown @@ -1080,6 +1218,9 @@ case $basic_machine in xps | xps100) basic_machine=xps100-honeywell ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; ymp) basic_machine=ymp-cray os=-unicos @@ -1088,6 +1229,10 @@ case $basic_machine in basic_machine=z8k-unknown os=-sim ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; none) basic_machine=none-none os=-none @@ -1126,7 +1271,7 @@ case $basic_machine in we32k) basic_machine=we32k-att ;; - sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) @@ -1173,9 +1318,12 @@ esac if [ x"$os" != x"" ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. + # First match some system type aliases + # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; @@ -1196,10 +1344,11 @@ case $os in # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ + | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ @@ -1208,9 +1357,10 @@ case $os in | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ @@ -1218,7 +1368,7 @@ case $os in | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1257,7 +1407,7 @@ case $os in -opened*) os=-openedition ;; - -os400*) + -os400*) os=-os400 ;; -wince*) @@ -1306,7 +1456,7 @@ case $os in -sinix*) os=-sysv4 ;; - -tpf*) + -tpf*) os=-tpf ;; -triton*) @@ -1348,6 +1498,11 @@ case $os in -zvmoe) os=-zvmoe ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; -none) ;; *) @@ -1370,6 +1525,12 @@ else # system, and we'll never get to this point. case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; *-acorn) os=-riscix1.2 ;; @@ -1379,9 +1540,21 @@ case $basic_machine in arm*-semi) os=-aout ;; - c4x-* | tic4x-*) - os=-coff - ;; + c4x-* | tic4x-*) + os=-coff + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 @@ -1400,13 +1573,13 @@ case $basic_machine in ;; m68000-sun) os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 ;; m68*-cisco) os=-aout ;; + mep-*) + os=-elf + ;; mips*-cisco) os=-elf ;; @@ -1431,7 +1604,7 @@ case $basic_machine in *-ibm) os=-aix ;; - *-knuth) + *-knuth) os=-mmixware ;; *-wec) @@ -1536,7 +1709,7 @@ case $basic_machine in -sunos*) vendor=sun ;; - -aix*) + -cnk*|-aix*) vendor=ibm ;; -beos*) From 4ea92a97ea438f912208ff98cf37d90646a76c9d Mon Sep 17 00:00:00 2001 From: David Adam Date: Sun, 22 Sep 2013 17:51:48 +0800 Subject: [PATCH 144/170] Update to newer install-sh version (Now from Automake 1.11.6.) --- install-sh | 676 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 476 insertions(+), 200 deletions(-) diff --git a/install-sh b/install-sh index 594a4edbf..a9244eb07 100755 --- a/install-sh +++ b/install-sh @@ -1,251 +1,527 @@ #!/bin/sh -# # install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). + +scriptversion=2011-01-19.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. # -# Copyright 1991 by the Massachusetts Institute of Technology +# Copyright (C) 1994 X Consortium # -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. +# from scratch. +nl=' +' +IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec else - true + doit_exec=$doit fi -if [ x"$dir_arg" != x ]; then - dst=$src - src="" +# Put in absolute file names if you don't have them in your path; +# or use environment vars. - if [ -d $dst ]; then - instcmd=: - chmodcmd="" - else - instcmd=mkdir - fi -else +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } ' -IFS="${IFS-${defaultIFS}}" -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" +posix_mkdir= -pathcomp='' +# Desired mode of installed file. +mode=0755 -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi +src= +dst= +dir_arg= +dst_arg= - pathcomp="${pathcomp}/" +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done fi -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 -# If we're going to rename the final executable, determine the name now. + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for `test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename + mkdir_mode= fi -# don't allow the sed command to completely eliminate the filename + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= else - true + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi fi + prefix=$prefix/ + done -# Make a temp file name in the proper directory. + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi - dsttmp=$dstdir/#inst.$$# + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else -# Move or copy the file name to the temp name + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ - $doit $instcmd $src $dsttmp && + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - trap "rm -f ${dsttmp}" 0 && + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && -# and set any options; do chmod last to preserve setuid bits + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && -# Now rename the file to the real destination. + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && -fi && + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + trap '' 0 + fi +done -exit 0 +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: From f2a52378029f4d6068e874873c30f935e93a5216 Mon Sep 17 00:00:00 2001 From: Ryan Hileman Date: Wed, 18 Sep 2013 17:19:30 -0700 Subject: [PATCH 145/170] Improve dangerous/undefined PID expansion behavior 1. Use Bash-like expansion for empty searches (when you just use a '%' by itself). '%' will now *only* match the last valid backgrounded process. If there are no such processes, an expansion error will be generated. '%' by itself would previously match either *all* backgrounded processes, or failing that, all processes owned by your user. If you ever tried to run `kill -9 %`, it would either kill all backgrounded processes or *all* of your processes. I'm not sure why anyone would ever want that to be a single keystroke away. You could almost typo it. As a result, `fg %`, `bg %`, `kill %`, etc will all operate on the last process touched by job control. 2. Don't run 'by-name' matches when the search term is numeric. This prevents you from running a command like `kill %1` and accidentally killing a process named something like "1Command". Overloaded behavior can be dangerous, and we probably shouldn't play fast and loose with expansion characters that generate process IDs. --- expand.cpp | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/expand.cpp b/expand.cpp index 4408a3e4b..45d292491 100644 --- a/expand.cpp +++ b/expand.cpp @@ -585,7 +585,30 @@ static int find_process(const wchar_t *proc, ASSERT_IS_MAIN_THREAD(); const job_t *j; - if (iswnumeric(proc) || (wcslen(proc)==0)) + // do the empty param check first, because an empty string passes our 'numeric' check + if (wcslen(proc)==0) + { + /* + This is an empty job expansion: '%' + It expands to the last job backgrounded. + */ + job_iterator_t jobs; + while ((j = jobs.next())) + { + if (!j->command_is_empty()) + { + append_completion(out, to_string(j->pgid)); + break; + } + } + /* + You don't *really* want to flip a coin between killing + the last process backgrounded and all processes, do you? + Let's not try other match methods with the solo '%' syntax. + */ + found = 1; + } + else if (iswnumeric(proc)) { /* This is a numeric job string, like '%2' @@ -611,11 +634,9 @@ static int find_process(const wchar_t *proc, 0); } } - } else { - int jid; wchar_t *end; @@ -624,15 +645,17 @@ static int find_process(const wchar_t *proc, if (jid > 0 && !errno && !*end) { j = job_get(jid); - if ((j != 0) && (j->command_wcstr() != 0)) + if ((j != 0) && (j->command_wcstr() != 0) && (!j->command_is_empty())) { - { - append_completion(out, to_string(j->pgid)); - found = 1; - } + append_completion(out, to_string(j->pgid)); } } } + /* + Stop here so you can't match a random process name + when you're just trying to use job control. + */ + found = 1; } if (found) return 1; From f76a16a727cf40beb1c79769ab06f9ee74fff509 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sun, 22 Sep 2013 20:10:39 +0200 Subject: [PATCH 146/170] Add Perl modules completion. --- share/completions/perl.fish | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/share/completions/perl.fish b/share/completions/perl.fish index 4754f6456..6266981d8 100644 --- a/share/completions/perl.fish +++ b/share/completions/perl.fish @@ -1,6 +1,8 @@ begin set -l unicode 'commandline | sgrep -qe "-[a-zA-Z]*C[a-zA-Z]*\$"' set -l noopt 'commandline | not sgrep -qe "-[a-zA-Z]*C[a-zA-Z]*\$"' + set -l modules "(find (perl -lE'print for @INC') -name '*.pm' -printf '%P\n' \ + | awk '{ gsub(\"/\", \"::\") } !/-/' RS=.pm\n | sort | uniq)" complete -c perl -s 0 -n $noopt --description 'Specify record separator' complete -c perl -s a -n $noopt --description 'Turn on autosplit mode' complete -c perl -s c -n $noopt --description 'Check syntax' @@ -26,8 +28,8 @@ begin complete -c perl -s i -n $noopt -x --description 'Edit files in-place' complete -c perl -s I -n $noopt -r --description 'Include path' complete -c perl -s l -n $noopt --description 'Automatic line ending processing' - complete -c perl -s m -n $noopt -x --description 'Require module' - complete -c perl -s M -n $noopt -x --description 'Use module' + complete -c perl -s m -n $noopt -x --description 'Require module' -a $modules + complete -c perl -s M -n $noopt -x --description 'Use module' -a $modules complete -c perl -s n -n $noopt --description 'Loop script' complete -c perl -s p -n $noopt --description 'Loop script, print $_' complete -c perl -s s -n $noopt --description 'Define custom switches' From 7ce5f34d6f2d86cc1e60b1830ac7a63bb478fb1f Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 22 Sep 2013 18:11:53 -0700 Subject: [PATCH 147/170] Disable flow control per #814 --- reader.cpp | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/reader.cpp b/reader.cpp index cf5427012..4696055f7 100644 --- a/reader.cpp +++ b/reader.cpp @@ -392,11 +392,12 @@ static volatile int interrupted=0; static bool is_backslashed(const wcstring &str, size_t pos); static wchar_t unescaped_quote(const wcstring &str, size_t pos); -/** - Stores the previous termios mode so we can reset the modes when - we execute programs and when the shell exits. -*/ -static struct termios saved_modes; +/** Mode on startup, which we restore on exit */ +static struct termios terminal_mode_on_startup; + +/** Mode we use to execute programs */ +static struct termios terminal_mode_for_executing_programs; + static void reader_super_highlight_me_plenty(size_t pos); @@ -415,7 +416,7 @@ static void term_donate() while (1) { - if (tcsetattr(0,TCSANOW,&saved_modes)) + if (tcsetattr(0, TCSANOW, &terminal_mode_for_executing_programs)) { if (errno != EINTR) { @@ -962,28 +963,37 @@ void reader_init() { VOMIT_ON_FAILURE(pthread_key_create(&generation_count_key, NULL)); - tcgetattr(0,&shell_modes); /* get the current terminal modes */ - memcpy(&saved_modes, - &shell_modes, - sizeof(saved_modes)); /* save a copy so we can reset the terminal later */ + /* Save the initial terminal mode */ + tcgetattr(STDIN_FILENO, &terminal_mode_on_startup); + /* Set the mode used for program execution, initialized to the current mode */ + memcpy(&terminal_mode_for_executing_programs, &terminal_mode_on_startup, sizeof terminal_mode_for_executing_programs); + terminal_mode_for_executing_programs.c_iflag &= ~IXON; /* disable flow control */ + terminal_mode_for_executing_programs.c_iflag &= ~IXOFF; /* disable flow control */ + + /* Set the mode used for the terminal, initialized to the current mode */ + memcpy(&shell_modes, &terminal_mode_on_startup, sizeof shell_modes); shell_modes.c_lflag &= ~ICANON; /* turn off canonical mode */ shell_modes.c_lflag &= ~ECHO; /* turn off echo mode */ + shell_modes.c_iflag &= ~IXON; /* disable flow control */ + shell_modes.c_iflag &= ~IXOFF; /* disable flow control */ shell_modes.c_cc[VMIN]=1; shell_modes.c_cc[VTIME]=0; +#if defined(_POSIX_VDISABLE) // PCA disable VDSUSP (typically control-Y), which is a funny job control // function available only on OS X and BSD systems // This lets us use control-Y for yank instead -#ifdef VDSUSP + #ifdef VDSUSP shell_modes.c_cc[VDSUSP] = _POSIX_VDISABLE; + #endif #endif } void reader_destroy() { - tcsetattr(0, TCSANOW, &saved_modes); + tcsetattr(0, TCSANOW, &terminal_mode_on_startup); pthread_key_delete(generation_count_key); } From 735af50ce9ee76f9d75dd592fb23a11e5881dc49 Mon Sep 17 00:00:00 2001 From: David Adam Date: Tue, 24 Sep 2013 20:04:05 +0800 Subject: [PATCH 148/170] default key bindings: add further iTerm2 bindings --- share/functions/fish_default_key_bindings.fish | 2 ++ 1 file changed, 2 insertions(+) diff --git a/share/functions/fish_default_key_bindings.fish b/share/functions/fish_default_key_bindings.fish index ff3d6faa9..2b68b28bd 100644 --- a/share/functions/fish_default_key_bindings.fish +++ b/share/functions/fish_default_key_bindings.fish @@ -79,6 +79,8 @@ function fish_default_key_bindings -d "Default (Emacs-like) key bindings for fis bind \ef forward-word bind \e\[1\;5C forward-word bind \e\[1\;5D backward-word + bind \e[1\;9B history-token-search-forward # iTerm2 + bind \e[1\;9A history-token-search-backward # iTerm2 bind \e\[1\;9C forward-word #iTerm2 bind \e\[1\;9D backward-word #iTerm2 bind \ed forward-kill-word From 1235e60a296a80af512cbd5e97c9167eb5226aef Mon Sep 17 00:00:00 2001 From: David Adam Date: Tue, 24 Sep 2013 22:49:11 +0800 Subject: [PATCH 149/170] default key bindings: fix syntax errors introduced in 735af50 --- share/functions/fish_default_key_bindings.fish | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/functions/fish_default_key_bindings.fish b/share/functions/fish_default_key_bindings.fish index 2b68b28bd..44821f36c 100644 --- a/share/functions/fish_default_key_bindings.fish +++ b/share/functions/fish_default_key_bindings.fish @@ -79,8 +79,8 @@ function fish_default_key_bindings -d "Default (Emacs-like) key bindings for fis bind \ef forward-word bind \e\[1\;5C forward-word bind \e\[1\;5D backward-word - bind \e[1\;9B history-token-search-forward # iTerm2 - bind \e[1\;9A history-token-search-backward # iTerm2 + bind \e\[1\;9A history-token-search-backward # iTerm2 + bind \e\[1\;9B history-token-search-forward # iTerm2 bind \e\[1\;9C forward-word #iTerm2 bind \e\[1\;9D backward-word #iTerm2 bind \ed forward-kill-word From 4aa9f76d06fb1761df0de22d2b174037d12f0cdb Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Wed, 25 Sep 2013 16:39:22 +0200 Subject: [PATCH 150/170] Fix one element tuple to be actually tuple. While in this case it doesn't mean much (neither `z` or `-` would be passed to options parser), it makes things possibly less buggy. --- share/tools/create_manpage_completions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/tools/create_manpage_completions.py b/share/tools/create_manpage_completions.py index 14bf13ee7..dc67f4c86 100755 --- a/share/tools/create_manpage_completions.py +++ b/share/tools/create_manpage_completions.py @@ -925,7 +925,7 @@ if __name__ == "__main__": show_progress = True elif opt in ('-c', '--cleanup-in'): cleanup_directories.append(value) - elif opt in ('-z'): + elif opt in ('-z',): DEROFF_ONLY = True else: assert False, "unhandled option" From 0d2af9e7422230b633fe228d3b40c6edd229a373 Mon Sep 17 00:00:00 2001 From: Siteshwar Vashisht Date: Sat, 28 Sep 2013 17:22:46 +0530 Subject: [PATCH 151/170] Updated help text of fish_config command --- doc_src/fish_config.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc_src/fish_config.txt b/doc_src/fish_config.txt index a9627bb23..777f25225 100644 --- a/doc_src/fish_config.txt +++ b/doc_src/fish_config.txt @@ -11,7 +11,7 @@ to make changes to your prompt and color configuration. you have finished, close the browser window and then press the Enter key to terminate the configuration session. -There are no parameters for fish_config. +fish_config optionally accepts name of the initial configuration tab. For e.g. fish_config history will start configuration interface with history tab. If the \c BROWSER environment variable is set, it will be used as the name of the web browser to open instead of the system default. From 991c900fc6d55de3c11f23d06b5c06393abb1b2d Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 29 Sep 2013 02:48:35 -0700 Subject: [PATCH 152/170] Set of changes to improve detection of escape sequences for prompt width computation. Addresses #767 --- fish_tests.cpp | 11 ++ screen.cpp | 333 ++++++++++++++++++++++++++----------------------- screen.h | 2 + 3 files changed, 192 insertions(+), 154 deletions(-) diff --git a/fish_tests.cpp b/fish_tests.cpp index b47ce3a3a..8b79ef3ac 100644 --- a/fish_tests.cpp +++ b/fish_tests.cpp @@ -550,6 +550,16 @@ static void test_utils() if (begin != a + wcslen(L"echo (echo (")) err(L"parse_util_cmdsubst_extent failed on line %ld", (long)__LINE__); } +static void test_escape_sequences(void) +{ + say(L"Testing escape codes"); + if (escape_code_length(L"") != 0) err(L"test_escape_sequences failed on line %d\n", __LINE__); + if (escape_code_length(L"abcd") != 0) err(L"test_escape_sequences failed on line %d\n", __LINE__); + if (escape_code_length(L"\x1b[2J") != 4) err(L"test_escape_sequences failed on line %d\n", __LINE__); + if (escape_code_length(L"\x1b[38;5;123mABC") != strlen("\x1b[38;5;123m")) err(L"test_escape_sequences failed on line %d\n", __LINE__); + if (escape_code_length(L"\x1b@") != 2) err(L"test_escape_sequences failed on line %d\n", __LINE__); +} + class lru_node_test_t : public lru_node_t { public: @@ -1834,6 +1844,7 @@ int main(int argc, char **argv) test_fork(); test_parser(); test_utils(); + test_escape_sequences(); test_lru(); test_expand(); test_fuzzy_match(); diff --git a/screen.cpp b/screen.cpp index 8c8438346..5ebe8605d 100644 --- a/screen.cpp +++ b/screen.cpp @@ -92,11 +92,9 @@ public: specified position of the specified wide character string. All of \c seq must match, but str may be longer than seq. */ -static int try_sequence(const char *seq, const wchar_t *str) +static size_t try_sequence(const char *seq, const wchar_t *str) { - int i; - - for (i=0;; i++) + for (size_t i=0; ; i++) { if (!seq[i]) return i; @@ -121,29 +119,6 @@ static size_t next_tab_stop(size_t in) return ((in/tab_width)+1)*tab_width; } -// PCA for term256 support, let's just detect the escape codes directly -static int is_term256_escape(const wchar_t *str) -{ - // An escape code looks like this: \x1b[38;5;m - // or like this: \x1b[48;5;m - - // parse out the required prefix - int len = try_sequence("\x1b[38;5;", str); - if (! len) len = try_sequence("\x1b[48;5;", str); - if (! len) return 0; - - // now try parsing out a string of digits - // we need at least one - if (! iswdigit(str[len])) return 0; - while (iswdigit(str[len])) len++; - - // look for the terminating m - if (str[len++] != L'm') return 0; - - // success - return len; -} - /* Like fish_wcwidth, but returns 0 for control characters instead of -1 */ static int fish_wcwidth_min_0(wchar_t wc) { @@ -157,6 +132,178 @@ static bool allow_soft_wrap(void) return !! auto_right_margin; } + +/* Returns the number of characters in the escape code starting at 'code' (which should initially contain \x1b) */ +size_t escape_code_length(const wchar_t *code) +{ + assert(code != NULL); + + /* The only escape codes we recognize start with \x1b */ + if (code[0] != L'\x1b') + return 0; + + size_t resulting_length = 0; + bool found = false; + + if (cur_term != NULL) + { + /* + Detect these terminfo color escapes with parameter + value 0..7, all of which don't move the cursor + */ + char * const esc[] = + { + set_a_foreground, + set_a_background, + set_foreground, + set_background, + }; + + for (size_t p=0; p < sizeof esc / sizeof *esc && !found; p++) + { + if (!esc[p]) + continue; + + for (size_t k=0; k<8; k++) + { + size_t len = try_sequence(tparm(esc[p],k), code); + if (len) + { + resulting_length = len; + found = true; + break; + } + } + } + } + + if (cur_term != NULL) + { + /* + Detect these semi-common terminfo escapes without any + parameter values, all of which don't move the cursor + */ + char * const esc2[] = + { + enter_bold_mode, + exit_attribute_mode, + enter_underline_mode, + exit_underline_mode, + enter_standout_mode, + exit_standout_mode, + flash_screen, + enter_subscript_mode, + exit_subscript_mode, + enter_superscript_mode, + exit_superscript_mode, + enter_blink_mode, + enter_italics_mode, + exit_italics_mode, + enter_reverse_mode, + enter_shadow_mode, + exit_shadow_mode, + enter_standout_mode, + exit_standout_mode, + enter_secure_mode + }; + + + + for (size_t p=0; p < sizeof esc2 / sizeof *esc2 && !found; p++) + { + if (!esc2[p]) + continue; + /* + Test both padded and unpadded version, just to + be safe. Most versions of tparm don't actually + seem to do anything these days. + */ + size_t len = maxi(try_sequence(tparm(esc2[p]), code), try_sequence(esc2[p], code)); + if (len) + { + resulting_length = len; + found = true; + } + } + } + + if (!found) + { + if (code[1] == L'k') + { + /* This looks like the escape sequence for setting a screen name */ + const env_var_t term_name = env_get_string(L"TERM"); + if (!term_name.missing() && string_prefixes_string(L"screen", term_name)) + { + const wchar_t * const screen_name_end_sentinel = L"\x1b\\"; + const wchar_t *screen_name_end = wcsstr(&code[2], screen_name_end_sentinel); + if (screen_name_end != NULL) + { + const wchar_t *escape_sequence_end = screen_name_end + wcslen(screen_name_end_sentinel); + resulting_length = escape_sequence_end - code; + } + else + { + /* Consider just k to be the code */ + resulting_length = 2; + } + found = true; + } + } + } + + if (! found) + { + /* Generic VT100 one byte sequence: CSI followed by something in the range @ through _ */ + if (code[1] == L'[' && (code[2] >= L'@' && code[2] <= L'_')) + { + resulting_length = 3; + found = true; + } + } + + if (! found) + { + /* Generic VT100 CSI-style sequence. , followed by zero or more ASCII characters NOT in the range [@,_], followed by one character in that range */ + if (code[1] == L'[') + { + // Start at 2 to skip over [ + size_t cursor = 2; + for (; code[cursor] != L'\0'; cursor++) + { + /* Consume a sequence of ASCII characters not in the range [@, ~] */ + wchar_t c = code[cursor]; + + /* If we're not in ASCII, just stop */ + if (c > 127) + break; + + /* If we're the end character, then consume it and then stop */ + if (c >= L'@' && c <= L'~') + { + cursor++; + break; + } + } + /* curs now indexes just beyond the end of the sequence (or at the terminating zero) */ + found = true; + resulting_length = cursor; + } + } + + if (! found) + { + /* Generic VT100 two byte sequence: followed by something in the range @ through _ */ + if (code[1] >= L'@' && code[1] <= L'_') + { + resulting_length = 2; + found = true; + } + } + + return resulting_length; +} + /* Information about a prompt layout */ struct prompt_layout_t { @@ -178,7 +325,7 @@ struct prompt_layout_t static prompt_layout_t calc_prompt_layout(const wchar_t *prompt) { size_t current_line_width = 0; - size_t j, k; + size_t j; prompt_layout_t prompt_layout = {}; prompt_layout.line_count = 1; @@ -187,134 +334,12 @@ static prompt_layout_t calc_prompt_layout(const wchar_t *prompt) { if (prompt[j] == L'\x1b') { - /* - This is the start of an escape code. Try to guess its width. - */ - size_t p; - int len=0; - bool found = false; - - /* - Detect these terminfo color escapes with parameter - value 0..7, all of which don't move the cursor - */ - char * const esc[] = + /* This is the start of an escape code. Skip over it if it's at least one character long. */ + size_t escape_len = escape_code_length(&prompt[j]); + if (escape_len > 0) { - set_a_foreground, - set_a_background, - set_foreground, - set_background, + j += escape_len - 1; } - ; - - /* - Detect these semi-common terminfo escapes without any - parameter values, all of which don't move the cursor - */ - char * const esc2[] = - { - enter_bold_mode, - exit_attribute_mode, - enter_underline_mode, - exit_underline_mode, - enter_standout_mode, - exit_standout_mode, - flash_screen, - enter_subscript_mode, - exit_subscript_mode, - enter_superscript_mode, - exit_superscript_mode, - enter_blink_mode, - enter_italics_mode, - exit_italics_mode, - enter_reverse_mode, - enter_shadow_mode, - exit_shadow_mode, - enter_standout_mode, - exit_standout_mode, - enter_secure_mode - } - ; - - for (p=0; p < sizeof esc / sizeof *esc && !found; p++) - { - if (!esc[p]) - continue; - - for (k=0; k<8; k++) - { - len = try_sequence(tparm(esc[p],k), &prompt[j]); - if (len) - { - j += (len-1); - found = true; - break; - } - } - } - - /* PCA for term256 support, let's just detect the escape codes directly */ - if (! found) - { - len = is_term256_escape(&prompt[j]); - if (len) - { - j += (len - 1); - found = true; - } - } - - - for (p=0; p < (sizeof(esc2)/sizeof(char *)) && !found; p++) - { - if (!esc2[p]) - continue; - /* - Test both padded and unpadded version, just to - be safe. Most versions of tparm don't actually - seem to do anything these days. - */ - len = maxi(try_sequence(tparm(esc2[p]), &prompt[j]), - try_sequence(esc2[p], &prompt[j])); - - if (len) - { - j += (len-1); - found = true; - } - } - - if (!found) - { - if (prompt[j+1] == L'k') - { - const env_var_t term_name = env_get_string(L"TERM"); - if (!term_name.missing() && string_prefixes_string(L"screen", term_name)) - { - const wchar_t *end; - j+=2; - found = true; - end = wcsstr(&prompt[j], L"\x1b\\"); - if (end) - { - /* - You'd thing this should be - '(end-prompt)+2', in order to move j - past the end of the string, but there is - a 'j++' at the end of each lap, so j - should always point to the last menged - character, e.g. +1. - */ - j = (end-prompt)+1; - } - else - { - break; - } - } - } - } - } else if (prompt[j] == L'\t') { diff --git a/screen.h b/screen.h index 0307fdd7d..1d9fde2c2 100644 --- a/screen.h +++ b/screen.h @@ -227,5 +227,7 @@ enum screen_reset_mode_t void s_reset(screen_t *s, screen_reset_mode_t mode); +/* Returns the length of an escape code. Exposed for testing purposes only. */ +size_t escape_code_length(const wchar_t *code); #endif From 843944f5580388fa0c754a4efba46c98485f4f8d Mon Sep 17 00:00:00 2001 From: MagicMuscleMan Date: Sun, 29 Sep 2013 13:35:03 +0200 Subject: [PATCH 153/170] Complete apt-get purge identical to apt-get remove As apt-get purge really has the same operations as apt-get remove, there is not reason to handle them differently in its completion file. --- share/completions/apt-get.fish | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/completions/apt-get.fish b/share/completions/apt-get.fish index 1f87d694c..4037df080 100644 --- a/share/completions/apt-get.fish +++ b/share/completions/apt-get.fish @@ -2,7 +2,7 @@ function __fish_apt_no_subcommand --description 'Test if apt has yet to be given the subcommand' for i in (commandline -opc) - if contains -- $i update upgrade dselect-upgrade dist-upgrade install remove source build-dep check clean autoclean + if contains -- $i update upgrade dselect-upgrade dist-upgrade install remove purge source build-dep check clean autoclean return 1 end end @@ -11,7 +11,7 @@ end function __fish_apt_use_package --description 'Test if apt command should have packages as potential completion' for i in (commandline -opc) - if contains -- $i contains install remove build-dep + if contains -- $i contains install remove purge build-dep return 0 end end From bf3cf2580f8e0965c3380872542f7b022ffdaf64 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 29 Sep 2013 13:39:41 -0700 Subject: [PATCH 154/170] Fix for bug where fish fails to source config files if the path contains a space --- fish.cpp | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/fish.cpp b/fish.cpp index 2251d8ecb..69dd6650e 100644 --- a/fish.cpp +++ b/fish.cpp @@ -210,31 +210,29 @@ static struct config_paths_t determine_config_directory_paths(const char *argv0) return paths; } +/* Source the file config.fish in the given directory */ +static void source_config_in_directory(const wcstring &dir) +{ + /* We want to execute a command like 'builtin source dir/config.fish 2>/dev/null' */ + const wcstring escaped_dir = escape_string(dir, ESCAPE_ALL); + const wcstring cmd = L"builtin source " + escaped_dir + L"/config.fish 2>/dev/null"; + parser_t &parser = parser_t::principal_parser(); + parser.eval(cmd, io_chain_t(), TOP); +} + /** Parse init files. exec_path is the path of fish executable as determined by argv[0]. */ static int read_init(const struct config_paths_t &paths) { - parser_t &parser = parser_t::principal_parser(); - const io_chain_t empty_ios; - parser.eval(L"builtin source " + paths.data + L"/config.fish 2>/dev/null", empty_ios, TOP); - parser.eval(L"builtin source " + paths.sysconf + L"/config.fish 2>/dev/null", empty_ios, TOP); + source_config_in_directory(paths.data); + source_config_in_directory(paths.sysconf); - - /* - We need to get the configuration directory before we can source the user configuration file - */ + /* We need to get the configuration directory before we can source the user configuration file. If path_get_config returns false then we have no configuration directory and no custom config to load. */ wcstring config_dir; - - /* - If path_get_config returns false then we have no configuration directory - and no custom config to load. - */ if (path_get_config(config_dir)) { - wcstring config_dir_escaped = escape_string(config_dir, 1); - wcstring eval_buff = format_string(L"builtin source %ls/config.fish 2>/dev/null", config_dir_escaped.c_str()); - parser.eval(eval_buff, empty_ios, TOP); + source_config_in_directory(config_dir); } return 1; From bb3a00d1eb047547cf779c462c65c36289137dde Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 29 Sep 2013 14:01:52 -0700 Subject: [PATCH 155/170] Fix fish.app for directories with spaces. Fixes #774 --- osx/launch_fish.scpt | Bin 4490 -> 4650 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/osx/launch_fish.scpt b/osx/launch_fish.scpt index dc39dd52e95d3dfd6996565471c3a899d6712004..3c1ae69e3b9710ac3623a75598cf15f377fb57b0 100644 GIT binary patch delta 1127 zcmZ9LOKcle6o$XC9Xqyj$DV{x2_&crPOAzjsc1r*v}uw)(?{H-aZBNb#6URy8 zIAw>#uB?zQd%8qONQCgJ)T$2_EKtLvAc_PbYBz|7*t5Bu86zQeasQ(^kN=$e&$(~C z@cxT$f9R|cr$q@^3qXka`rUVfR$aTHDJMrKT}r@@b&}Pap=?{0ZhCk{i3tu9-~cCd zZ&T;!VS3GD^GMN4U`DtOaF{+0DS`jK`^3|)1gu3revl(JN3hlza2TM4IbN4jU?;m3 z{rbJ8=Vla#8tFpCpv|C{KIAYYop)R2F<9miggHpiY;)B78WR(WEfmWY#ZdzLrBy#e zW{YDnfl#b)wOmykYp@P5sN>=Eo)NMf4{%&qPjFHR1S?pKFk*h<6vLJn8Ss>TGu#~= z_GUQka9ZC9=XRWwnlt91;!Hyip)x;mR_}}KdgH7|(CsoPM>rE0#R zpl`)?6$%ZdT;`cIo94b^wxNvYnWLx#e5G89yhce0_)58wShgv91I;^<{KOiS8cNMF zr@P|qgG$Q%x}uaU*erN;6^Dw470Y@pv9IR}E0*~Jl3bBq_u}Rri7w(5 zw_YujroEpCHY-Gu<}S_Vj=4=u+WwN*8LbD+Ei9Y54kw?tYPuu&a?dJlESVduna@d? z&&;Rh6DG{Z@~#HWhWW^>%My)yca2F>D7L&(sM)OPYsqU(SGQZK=^ai-ZvStsytH?| zg=qRI+J3*D`Xlw{-oNHMD=pZQv|g0=75V#m$|aeSBs-Jk8L4P@aXe?M?@asknM?w= OR#=h8qyE|2`ru!~Oa_tw delta 981 zcmZ8gOH5Ni6g~4=3cPmOK0k4RF$9623&AKV1zM25wp1v!KntZ5uq~(rOw^TYU73t~ zS(BJp>pvJJE?gM!|JxwZm>4y(bD@jteeFu~GH2e*oqOiobKhI6ytMQ3bt3~i9Fjpy z1F#~UUA}4&X_c_Xi~-c5PBP?UwFs$I>(J&9>Tv)EB~O+fXgGv+63&9 z+BkC^LL)y-l0lrzuN%!5kjkmRu*^|ZIZz<0|7t$ z^a1VQn?3*zmY%iMmv)$%It_HH4cqXxHqPmy_Yz%&0-1{5p<9g=S6t{eX^NO8h#q=F zuO-+5vs!cK2#!jIe6@ZA;CJ#iGY1S_{8Q~wh|`=DKrg+r(<{h2luo7RQ}NlvnUv|k z8xvjw8of2)y$N3cRaYXdy)N|TT1!?$O$2EKHNIKHG4x4>e321E=q36Q5bh+433trWCs*1lp^ z{EPv^JQDO&B2kc#L`wa#*SjJG@(61jcVV0zSr+P#+*+J;At}~NRI8&umv&wewh4M7 zF`+E(z4l2=33?2;F{ym+GWQgU-L#AndPEO#f|)b!@?B{QJ%DhsBLcK!r=|bn2q1&NxsS+ydj+>)G From 488652c23a2d0cdaf3eaef96e6db22bb1162e2ca Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Mon, 30 Sep 2013 14:45:12 +0200 Subject: [PATCH 156/170] Support term256 in config.fish. Fixes #1022. --- fish.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fish.cpp b/fish.cpp index 69dd6650e..24499c755 100644 --- a/fish.cpp +++ b/fish.cpp @@ -61,6 +61,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "output.h" #include "history.h" #include "path.h" +#include "input.h" /* PATH_MAX may not exist */ #ifndef PATH_MAX @@ -419,6 +420,8 @@ int main(int argc, char **argv) env_init(&paths); reader_init(); history_init(); + /* For setcolor to support term256 in config.fish (#1022) */ + update_fish_term256(); parser_t &parser = parser_t::principal_parser(); From 6c70ed79ae523ea730ba29ff2e84da41a6b5e230 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 30 Sep 2013 11:45:29 -0700 Subject: [PATCH 157/170] Update docs to describe autosuggestions. Fixes #937 --- doc_src/index.hdr.in | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc_src/index.hdr.in b/doc_src/index.hdr.in index 5886340de..25fcac640 100644 --- a/doc_src/index.hdr.in +++ b/doc_src/index.hdr.in @@ -376,6 +376,20 @@ Help on a specific builtin can also be obtained with the -h parameter. For instance, to obtain help on the \c fg builtin, either type fg -h or help fg. +\section autosuggestions Autosuggestions + +fish suggests commands as you type, based on command history, completions, +and valid file paths. As you type commands, you will see a completion offered after the +cursor, in a muted gray color (which can be changed with the +fish_color_autosuggestion variable). + +To accept the autosuggestion (replacing the command line contents), +hit right arrow or Control-F. If the autosuggestion is not what you want, +just ignore it: it won't execute unless you accept it. + +Autosuggestions are a powerful way to quickly summon frequently entered commands, by +typing the first few characters. They are also an efficient technique for navigating +through directory hierarchies. \section completion Tab completion From cbe615224da57e96cfe609eb92f115e0d45f0f28 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 30 Sep 2013 13:57:36 -0700 Subject: [PATCH 158/170] Make tok_last_type return an enum token_type instead of int --- builtin_commandline.cpp | 6 +++++- complete.cpp | 5 +++++ parse_util.cpp | 5 +++++ parser.cpp | 7 ++++--- reader.cpp | 7 +++++++ tokenizer.cpp | 14 +++++++------- tokenizer.h | 5 ++--- 7 files changed, 35 insertions(+), 14 deletions(-) diff --git a/builtin_commandline.cpp b/builtin_commandline.cpp index c1bf7de0d..5564d05b7 100644 --- a/builtin_commandline.cpp +++ b/builtin_commandline.cpp @@ -169,7 +169,11 @@ static void write_part(const wchar_t *begin, out.push_back(L'\n'); break; } - + + default: + { + break; + } } } diff --git a/complete.cpp b/complete.cpp index 7b0b41735..6f5da9ec3 100644 --- a/complete.cpp +++ b/complete.cpp @@ -1915,6 +1915,11 @@ void complete(const wcstring &cmd, std::vector &comps, completion_ end_loop=1; break; } + + default: + { + break; + } } if (tok_get_pos(&tok) >= (long)pos) diff --git a/parse_util.cpp b/parse_util.cpp index dca23d3ef..2f95a3e25 100644 --- a/parse_util.cpp +++ b/parse_util.cpp @@ -381,6 +381,11 @@ static void job_or_process_extent(const wchar_t *buff, break; } + + default: + { + break; + } } } diff --git a/parser.cpp b/parser.cpp index 93e068d78..49e5a9661 100644 --- a/parser.cpp +++ b/parser.cpp @@ -154,7 +154,7 @@ The fish parser. Contains functions for parsing and evaluating code. /** Error message for Posix-style assignment */ -#define COMMAND_ASSIGN_ERR_MSG _( L"Unknown command '%ls'. Did you mean 'set %ls %ls'? For information on assigning values to variables, see the help section on the set command by typing 'help set'.") +#define COMMAND_ASSIGN_ERR_MSG _( L"Unknown command '%ls'. Did you mean 'set %ls %ls'? See the help section on the set command by typing 'help set'.") /** Error for invalid redirection token @@ -2012,8 +2012,9 @@ int parser_t::parse_job(process_t *p, if (! has_command && ! use_implicit_cd) { - int tmp; const wchar_t *cmd = args.at(0).completion.c_str(); + + fprintf(stderr, "arg count: %lu\n", args.size()); /* We couldn't find the specified command. @@ -2095,7 +2096,7 @@ int parser_t::parse_job(process_t *p, event_fire_generic(L"fish_command_not_found", &event_args); } - tmp = current_tokenizer_pos; + int tmp = current_tokenizer_pos; current_tokenizer_pos = tok_get_pos(tok); fwprintf(stderr, L"%ls", parser_t::current_line()); diff --git a/reader.cpp b/reader.cpp index 4696055f7..228fa9183 100644 --- a/reader.cpp +++ b/reader.cpp @@ -2331,6 +2331,13 @@ static void handle_token_history(int forward, int reset) } } + break; + + default: + { + break; + } + } } } diff --git a/tokenizer.cpp b/tokenizer.cpp index 4521c164d..62094f92c 100644 --- a/tokenizer.cpp +++ b/tokenizer.cpp @@ -93,7 +93,7 @@ int tok_get_error(tokenizer_t *tok) } -tokenizer_t::tokenizer_t(const wchar_t *b, tok_flags_t flags) : buff(NULL), orig_buff(NULL), last_type(0), last_pos(0), has_next(false), accept_unfinished(false), show_comments(false), last_quote(0), error(0), squash_errors(false), cached_lineno_offset(0), cached_lineno_count(0) +tokenizer_t::tokenizer_t(const wchar_t *b, tok_flags_t flags) : buff(NULL), orig_buff(NULL), last_type(TOK_NONE), last_pos(0), has_next(false), accept_unfinished(false), show_comments(false), last_quote(0), error(0), squash_errors(false), cached_lineno_offset(0), cached_lineno_count(0) { /* We can only generate error messages on the main thread due to wgettext() thread safety issues. */ @@ -116,7 +116,7 @@ tokenizer_t::tokenizer_t(const wchar_t *b, tok_flags_t flags) : buff(NULL), orig tok_next(this); } -int tok_last_type(tokenizer_t *tok) +enum token_type tok_last_type(tokenizer_t *tok) { CHECK(tok, TOK_ERROR); CHECK(tok->buff, TOK_ERROR); @@ -440,7 +440,7 @@ static void read_comment(tokenizer_t *tok) */ static void read_redirect(tokenizer_t *tok, int fd) { - int mode = -1; + enum token_type redirection_mode = TOK_NONE; if ((*tok->buff == L'>') || (*tok->buff == L'^')) @@ -449,11 +449,11 @@ static void read_redirect(tokenizer_t *tok, int fd) if (*tok->buff == *(tok->buff-1)) { tok->buff++; - mode = 1; + redirection_mode = TOK_REDIRECT_APPEND; } else { - mode = 0; + redirection_mode = TOK_REDIRECT_OUT; } if (*tok->buff == L'|') @@ -472,7 +472,7 @@ static void read_redirect(tokenizer_t *tok, int fd) else if (*tok->buff == L'<') { tok->buff++; - mode = 2; + redirection_mode = TOK_REDIRECT_IN; } else { @@ -493,7 +493,7 @@ static void read_redirect(tokenizer_t *tok, int fd) } else { - tok->last_type = TOK_REDIRECT_OUT + mode; + tok->last_type = redirection_mode; } } diff --git a/tokenizer.h b/tokenizer.h index 4357757dc..42516a1b5 100644 --- a/tokenizer.h +++ b/tokenizer.h @@ -77,7 +77,7 @@ struct tokenizer_t wcstring last_token; /** Type of last token*/ - int last_type; + enum token_type last_type; /** Offset of last token*/ size_t last_pos; @@ -123,7 +123,7 @@ void tok_next(tokenizer_t *tok); /** Returns the type of the last token. Must be one of the values in the token_type enum. */ -int tok_last_type(tokenizer_t *tok); +enum token_type tok_last_type(tokenizer_t *tok); /** Returns the last token string. The string should not be freed by the caller. @@ -150,7 +150,6 @@ int tok_get_pos(tokenizer_t *tok); */ const wchar_t *tok_string(tokenizer_t *tok); - /** Returns only the first token from the specified string. This is a convenience function, used to retrieve the first token of a From 2f33e5919d2e3eb1a08cdd44a34f779a50ad2242 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 30 Sep 2013 14:55:25 -0700 Subject: [PATCH 159/170] Better error messages for `EDITOR=vim git...` type commands. https://github.com/fish-shell/fish-shell/issues/809 --- parser.cpp | 48 +++++++++++++++++++++++++++++++++--------------- tokenizer.cpp | 25 +++++++++++++++++++++++++ tokenizer.h | 3 +++ 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/parser.cpp b/parser.cpp index 49e5a9661..72b46c9f8 100644 --- a/parser.cpp +++ b/parser.cpp @@ -152,7 +152,7 @@ The fish parser. Contains functions for parsing and evaluating code. #define INVALID_END_ERR_MSG _( L"'end' command outside of block") /** - Error message for Posix-style assignment + Error message for Posix-style assignment: foo=bar */ #define COMMAND_ASSIGN_ERR_MSG _( L"Unknown command '%ls'. Did you mean 'set %ls %ls'? See the help section on the set command by typing 'help set'.") @@ -2014,8 +2014,6 @@ int parser_t::parse_job(process_t *p, const wchar_t *cmd = args.at(0).completion.c_str(); - fprintf(stderr, "arg count: %lu\n", args.size()); - /* We couldn't find the specified command. @@ -2034,19 +2032,39 @@ int parser_t::parse_job(process_t *p, and zsh). */ - if (wcschr(cmd, L'=')) + const wchar_t * const equals_ptr = wcschr(cmd, L'='); + if (equals_ptr != NULL) { - wchar_t *cpy = wcsdup(cmd); - wchar_t *valpart = wcschr(cpy, L'='); - *valpart++=0; - - debug(0, - COMMAND_ASSIGN_ERR_MSG, - cmd, - cpy, - valpart); - free(cpy); - + /* Try to figure out if this is a pure variable assignment (foo=bar), or if this appears to be running a command (foo=bar ruby...) */ + + const wcstring name_str = wcstring(cmd, equals_ptr - cmd); //variable name, up to the = + const wcstring val_str = wcstring(equals_ptr + 1); //variable value, past the = + + wcstring next_str; + if (tok_peek_next(tok, &next_str) == TOK_STRING && ! next_str.empty()) + { + wcstring ellipsis_str = wcstring(1, ellipsis_char); + if (ellipsis_str == L"$") + ellipsis_str = L"..."; + + /* Looks like a command */ + debug(0, + _( L"Unknown command '%ls'. Did you mean to run %ls with a modified environment? Try 'env %ls=%ls %ls%ls'. See the help section on the set command by typing 'help set'."), + cmd, + next_str.c_str(), + name_str.c_str(), + val_str.c_str(), + next_str.c_str(), + ellipsis_str.c_str()); + } + else + { + debug(0, + COMMAND_ASSIGN_ERR_MSG, + cmd, + name_str.c_str(), + val_str.c_str()); + } } else if (cmd[0]==L'$' || cmd[0] == VARIABLE_EXPAND || cmd[0] == VARIABLE_EXPAND_SINGLE) { diff --git a/tokenizer.cpp b/tokenizer.cpp index 62094f92c..567b03dcd 100644 --- a/tokenizer.cpp +++ b/tokenizer.cpp @@ -641,6 +641,31 @@ void tok_next(tokenizer_t *tok) } +enum token_type tok_peek_next(tokenizer_t *tok, wcstring *out_next_string) +{ + if (out_next_string != NULL) + { + out_next_string->clear(); + } + + enum token_type result = TOK_END; + if (tok_has_next(tok)) + { + int saved = tok_get_pos(tok); + tok_next(tok); + result = tok_last_type(tok); + + if (out_next_string != NULL) + { + const wchar_t *last = tok_last(tok); + out_next_string->assign(last ? last : L""); + } + + tok_set_pos(tok, saved); + } + return result; +} + const wchar_t *tok_string(tokenizer_t *tok) { return tok?tok->orig_buff:0; diff --git a/tokenizer.h b/tokenizer.h index 42516a1b5..027f2d6d7 100644 --- a/tokenizer.h +++ b/tokenizer.h @@ -145,6 +145,9 @@ int tok_has_next(tokenizer_t *tok); */ int tok_get_pos(tokenizer_t *tok); +/** Returns the token type after the current one, without adjusting the position. Optionally returns the next string by reference. */ +enum token_type tok_peek_next(tokenizer_t *tok, wcstring *out_next_string); + /** Returns the original string to tokenizer */ From 084e435883cd3eb83d2385c2c7cc7b029f45ecf9 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 30 Sep 2013 16:03:34 -0700 Subject: [PATCH 160/170] Strip out git commit numbers from doxygen documentation --- Makefile.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 7b243ee77..e0bc9fdb5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -324,9 +324,10 @@ prof: all # Depend on the sources (*.hdr.in) and manually make the # intermediate *.hdr and doc.h files if needed +# The sed command deletes everything including and after the first -, for simpler version numbers user_doc: $(HDR_FILES_SRC) Doxyfile.user user_doc.head.html $(HELP_SRC) doc.h $(HDR_FILES) - (cat Doxyfile.user ; echo PROJECT_NUMBER=$(FISH_BUILD_VERSION)) | doxygen - && touch user_doc + (cat Doxyfile.user ; echo PROJECT_NUMBER=$(FISH_BUILD_VERSION) | sed "s/-.*//") | doxygen - && touch user_doc # From 6c82e7acda212c7de5e0e8c46d4ba5f1b12fc061 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Tue, 1 Oct 2013 08:25:13 +0200 Subject: [PATCH 161/170] Support implicit cd with appended `/`. This is an experimental feature, proposed in the issue #22. https://github.com/fish-shell/fish-shell/issues/22#issuecomment-20483478 --- path.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/path.cpp b/path.cpp index 3a0b9c83d..4649e8051 100644 --- a/path.cpp +++ b/path.cpp @@ -315,6 +315,7 @@ bool path_can_be_implicit_cd(const wcstring &path, wcstring *out_path, const wch if (string_prefixes_string(L"/", exp_path) || string_prefixes_string(L"./", exp_path) || string_prefixes_string(L"../", exp_path) || + string_suffixes_string(L"/", exp_path) || exp_path == L"..") { /* These paths can be implicit cd, so see if you cd to the path. Note that a single period cannot (that's used for sourcing files anyways) */ From a62ebc9a69ac57f74b9bcaa52813eaefd79aede2 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Tue, 1 Oct 2013 08:29:40 +0200 Subject: [PATCH 162/170] Restore directories' tab completion without slash in command. This is needed for implicit cd when ending command with `/`. --- complete.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/complete.cpp b/complete.cpp index 6f5da9ec3..8df02b35a 100644 --- a/complete.cpp +++ b/complete.cpp @@ -1141,22 +1141,18 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool if (cdpath.missing_or_empty()) cdpath = L"."; - if (str_cmd.find(L'/') != wcstring::npos || str_cmd.at(0) == L'~') + if (use_command) { - if (use_command) + if (expand_string(str_cmd, this->completions, ACCEPT_INCOMPLETE | EXECUTABLES_ONLY | this->expand_flags()) != EXPAND_ERROR) { - - if (expand_string(str_cmd, this->completions, ACCEPT_INCOMPLETE | EXECUTABLES_ONLY | this->expand_flags()) != EXPAND_ERROR) + if (this->wants_descriptions()) { - if (this->wants_descriptions()) - { - this->complete_cmd_desc(str_cmd); - } + this->complete_cmd_desc(str_cmd); } } } - else + if (str_cmd.find(L'/') == wcstring::npos && str_cmd.at(0) != L'~') { if (use_command) { From 6990871efd032acec88ae4272be20b1d144c3509 Mon Sep 17 00:00:00 2001 From: nulltrek Date: Wed, 25 Sep 2013 22:25:04 +0200 Subject: [PATCH 163/170] Fix git completions when aliased command is not found. --- share/completions/git.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/completions/git.fish b/share/completions/git.fish index 138b2c4a5..d4b9fcf34 100644 --- a/share/completions/git.fish +++ b/share/completions/git.fish @@ -53,7 +53,7 @@ function __fish_git_using_command end # aliased command - set -l aliased (command git config --get "alias.$cmd[2]" | sed 's/ .*$//') + set -l aliased (command git config --get "alias.$cmd[2]" ^ /dev/null | sed 's/ .*$//') if [ $argv[1] = "$aliased" ] return 0 end From 00a890c8c7f03fd1a7aaeddec09cfa48020f0ad7 Mon Sep 17 00:00:00 2001 From: David Adam Date: Sun, 22 Sep 2013 19:54:09 +0800 Subject: [PATCH 164/170] configure: use C++ for all tests, kill CFLAGS --- configure.ac | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 21e043afc..ea7c592f2 100644 --- a/configure.ac +++ b/configure.ac @@ -98,18 +98,18 @@ fi # AC_PROG_CXX([g++ c++]) -AC_PROG_CPP AC_PROG_INSTALL +AC_LANG(C++) echo "CXXFLAGS: $CXXFLAGS" # # Detect directories which may contain additional headers, libraries # and commands. This needs to be done early - before Autoconf starts -# to mess with CFLAGS and all the other environemnt variables. +# to mess with CXXFLAGS and all the other environemnt variables. # # This mostly helps OS X users, since fink usually installs out of -# tree and doesn't update CFLAGS. +# tree and doesn't update CXXFLAGS. # # It also helps FreeBSD which puts libiconv in /usr/local/lib @@ -119,7 +119,6 @@ for i in /usr/pkg /sw /opt /opt/local /usr/local; do if test -d $i/include; then AC_MSG_RESULT(yes) CXXFLAGS="$CXXFLAGS -I$i/include/" - CFLAGS="$CFLAGS -I$i/include/" else AC_MSG_RESULT(no) fi @@ -329,7 +328,7 @@ if test "$glibc" = yes; then # fallback.h, in order to keep fish working on non-gnu platforms. # - CFLAGS="$CFLAGS -D_GNU_SOURCE=1 -D_ISO99_SOURCE=1" + CXXFLAGS="$CXXFLAGS -D_GNU_SOURCE=1 -D_ISO99_SOURCE=1" else AC_MSG_RESULT(no) fi @@ -606,7 +605,7 @@ AC_CHECK_HEADER( # conditional definition of __EXTENSIONS__, to avoid redundant tests. # -XCFLAGS="$CXXFLAGS" +XCXXFLAGS="$CXXFLAGS" echo checking how to use -D_XOPEN_SOURCE=600 and -D_POSIX_C_SOURCE=200112L... local_found_posix_switch=no @@ -614,7 +613,7 @@ local_found_posix_switch=no for i in "" "-D_POSIX_C_SOURCE=200112L" "-D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112L"; do AC_MSG_CHECKING( if switches \"$i\" works) - CFLAGS="$XCFLAGS $i" + CXXFLAGS="$XCXXFLAGS $i" # # Try to run this program, which should test various extensions @@ -688,7 +687,7 @@ done # if test ! x$local_found_posix_switch = xyes; then - CFLAGS="$XCFLAGS" + CXXFLAGS="$XCXXFLAGS" fi From 0efa211a05841c3ceb2f3012bdeb6cc0633842a1 Mon Sep 17 00:00:00 2001 From: sra Date: Thu, 3 Oct 2013 11:46:58 +0200 Subject: [PATCH 165/170] Use manpath instead of man --path in man.fish function (as in commit c7941fc). --- share/functions/man.fish | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/functions/man.fish b/share/functions/man.fish index cb11d6559..2b9bab517 100644 --- a/share/functions/man.fish +++ b/share/functions/man.fish @@ -8,7 +8,7 @@ function man --description "Format and display the on-line manual pages" set -l fish_manpath (dirname $__fish_datadir)/fish/man if test -d "$fish_manpath" # Notice local but exported variable - set -lx MANPATH "$fish_manpath":(command man --path) + set -lx MANPATH "$fish_manpath":(command manpath) # Invoke man with this manpath, and we're done command man $argv From 238bbfcbbb365867cfc57d0697413b6ba39c2421 Mon Sep 17 00:00:00 2001 From: Ronaldo Maia Date: Wed, 2 Oct 2013 14:33:58 -0300 Subject: [PATCH 166/170] Add postgres psql completion Options and descriptions are from psql --help output. Database and username completion based on the bash completion --- share/completions/psql.fish | 66 +++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 share/completions/psql.fish diff --git a/share/completions/psql.fish b/share/completions/psql.fish new file mode 100644 index 000000000..a6c7c6766 --- /dev/null +++ b/share/completions/psql.fish @@ -0,0 +1,66 @@ + +function __fish_complete_pg_database + psql -AtqwlF \t ^/dev/null | awk 'NF > 1 { print $1 }' +end + +function __fish_complete_pg_user + psql -Atqwc 'select usename from pg_user' template1 ^/dev/null +end + +complete -c psql --no-files -a '(__fish_complete_pg_database)' + + +# +# General options: +# + +complete -c psql -s c -l command --description "run only single command (SQL or internal) and exit" +complete -c psql -s d -l dbname -a '(__fish_complete_pg_database)' --description "database name to connect to (default: "romaia")" +complete -c psql -s f -l file -r --description "execute commands from file, then exit" +complete -c psql -s l -l list --description "list available databases, then exit" + +# complete -c psql -s v -l set=, --variable=NAME=VALUE +# set psql variable NAME to VALUE + +complete -c psql -s X -l no-psqlrc --description "do not read startup file (~/.psqlrc)" +complete -c psql -s 1 -l single-transaction --description "execute command file as a single transaction" +complete -c psql -l help --description "show this help, then exit" +complete -c psql -l version --description "output version information, then exit" + +# +# Input and output options: +# + +complete -c psql -s a, -l echo-all --description "echo all input from script" +complete -c psql -s e, -l echo-queries --description "echo commands sent to server" +complete -c psql -s E, -l echo-hidden --description "display queries that internal commands generate" +complete -c psql -s L, -l log-file --description "send session log to file" +complete -c psql -s n, -l no-readline --description "disable enhanced command line editing (readline)" +complete -c psql -s o, -l output --description "send query results to file (or |pipe)" +complete -c psql -s q, -l quiet --description "run quietly (no messages, only query output)" +complete -c psql -s s, -l single-step --description "single-step mode (confirm each query)" +complete -c psql -s S, -l single-line --description "single-line mode (end of line terminates SQL command)" + +# +# Output format options: +# + +complete -c psql -s A, -l no-align --description "unaligned table output mode" +complete -c psql -s H, -l html --description "HTML table output mode" +complete -c psql -s P, -l pset --description "set printing option VAR to ARG (see \pset command)" +complete -c psql -s t, -l tuples-only --description "print rows only" +complete -c psql -s T, -l table-attr --description "set HTML table tag attributes (e.g., width, border)" +complete -c psql -s x, -l expanded --description "turn on expanded table output" +complete -c psql -s F, -l field-separator --description "set field separator (default: '|')" +complete -c psql -s R, -l record-separator --description "set record separator (default: newline)" + + +# +# Connection options +# + +complete -c psql -s h -l host -a '(__fish_print_hostnames)' --description "database server host or socket directory" +complete -c psql -s p -l port -x --description "database server port" +complete -c psql -s U -l username -a '(__fish_complete_pg_user)' --description "database user name" +complete -c psql -s w -l no-password --description "never prompt for password" +complete -c psql -s W -l password --description "force password prompt (should happen automatically)" From 3788f462b401e9661c5dd478817c01519e910844 Mon Sep 17 00:00:00 2001 From: Ronaldo Maia Date: Wed, 2 Oct 2013 14:33:58 -0300 Subject: [PATCH 167/170] Add postgres psql completion Options and descriptions are from psql --help output. Database and username completion based on the bash completion --- share/completions/psql.fish | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/share/completions/psql.fish b/share/completions/psql.fish index a6c7c6766..5b67a33d6 100644 --- a/share/completions/psql.fish +++ b/share/completions/psql.fish @@ -14,18 +14,18 @@ complete -c psql --no-files -a '(__fish_complete_pg_database)' # General options: # -complete -c psql -s c -l command --description "run only single command (SQL or internal) and exit" -complete -c psql -s d -l dbname -a '(__fish_complete_pg_database)' --description "database name to connect to (default: "romaia")" -complete -c psql -s f -l file -r --description "execute commands from file, then exit" -complete -c psql -s l -l list --description "list available databases, then exit" +complete -c psql -s d -l dbname -a '(__fish_complete_pg_database)' --description "database name to connect to" +complete -c psql -s c -l command --description "run only single command (SQL or internal) and exit" +complete -c psql -s f -l file -r --description "execute commands from file, then exit" +complete -c psql -s l -l list --description "list available databases, then exit" # complete -c psql -s v -l set=, --variable=NAME=VALUE # set psql variable NAME to VALUE complete -c psql -s X -l no-psqlrc --description "do not read startup file (~/.psqlrc)" complete -c psql -s 1 -l single-transaction --description "execute command file as a single transaction" -complete -c psql -l help --description "show this help, then exit" -complete -c psql -l version --description "output version information, then exit" +complete -c psql -l help --description "show this help, then exit" +complete -c psql -l version --description "output version information, then exit" # # Input and output options: From ad5ae9ba3b2107ac68f55ead4c7292cd1de23fc1 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 5 Oct 2013 00:37:44 -0700 Subject: [PATCH 168/170] New documentation UI, including tutorial. --- Makefile.in | 20 +- doc_src/commands.hdr.in | 13 +- doc_src/design.hdr | 4 + doc_src/faq.hdr | 15 +- doc_src/index.hdr.in | 11 +- doc_src/license.hdr | 4 + doc_src/tutorial.hdr | 746 ++++++++++++++++++++++++++++++++++++++++ user_doc.head.html | 153 +++++++- 8 files changed, 936 insertions(+), 30 deletions(-) create mode 100644 doc_src/tutorial.hdr diff --git a/Makefile.in b/Makefile.in index e0bc9fdb5..2e3a03e30 100644 --- a/Makefile.in +++ b/Makefile.in @@ -153,9 +153,10 @@ MIME_OBJS := mimedb.o print_help.o xdgmimealias.o xdgmime.o \ # # These files are the source files, they contain a few @FOO@-style substitutions +# Note that this order defines the order that they appear in the documentation # -HDR_FILES_SRC := doc_src/index.hdr.in doc_src/commands.hdr.in doc_src/design.hdr doc_src/license.hdr doc_src/faq.hdr +HDR_FILES_SRC := doc_src/index.hdr.in doc_src/tutorial.hdr doc_src/design.hdr doc_src/license.hdr doc_src/commands.hdr.in doc_src/faq.hdr # @@ -330,6 +331,7 @@ user_doc: $(HDR_FILES_SRC) Doxyfile.user user_doc.head.html $(HELP_SRC) doc.h $( (cat Doxyfile.user ; echo PROJECT_NUMBER=$(FISH_BUILD_VERSION) | sed "s/-.*//") | doxygen - && touch user_doc + # # Source code documentation. Also includes user documentation. # @@ -365,26 +367,34 @@ test: $(PROGRAMS) fish_tests # doc_src/commands.hdr:$(HELP_SRC) doc_src/commands.hdr.in - -rm command_list.tmp $@ + -rm command_list.tmp command_list_toc.tmp $@ for i in `printf "%s\n" $(HELP_SRC)|sort`; do \ echo "
" >>command_list.tmp; \ cat $$i >>command_list.tmp; \ echo >>command_list.tmp; \ echo >>command_list.tmp; \ + NAME=`basename $$i .txt`; \ + echo '- '$$NAME'' >> command_list_toc.tmp; \ echo "Back to index". >>command_list.tmp; \ done mv command_list.tmp command_list.txt - cat $@.in | awk '{if ($$0 ~ /@command_list@/){ system("cat command_list.txt");} else{ print $$0;}}' >$@ + mv command_list_toc.tmp command_list_toc.txt + cat $@.in | awk '{if ($$0 ~ /@command_list_toc@/) { system("cat command_list_toc.txt"); } else if ($$0 ~ /@command_list@/){ system("cat command_list.txt");} else{ print $$0;}}' >$@ toc.txt: $(HDR_FILES:index.hdr=index.hdr.in) -rm toc.tmp $@ + # Ugly hack to set the toc initial title for the main page + echo '- Documentation' > toc.tmp + # The first sed command captures the page name, followed by the description + # The second sed command captures the command name \1 and the description \2, but only up to a dash + # This is to reduce the size of the TOC in the command listing on the main page for i in $(HDR_FILES:index.hdr=index.hdr.in); do\ NAME=`basename $$i .hdr`; \ NAME=`basename $$NAME .hdr.in`; \ sed <$$i >>toc.tmp -n \ -e 's,.*\\page *\([^ ]*\) *\(.*\)$$,- \2,p' \ - -e 's,.*\\section *\([^ ]*\) *\(.*\)$$, - \2,p'; \ + -e 's,.*\\section *\([^ ]*\) *\([^-]*\)\(.*\)$$, - \2,p'; \ done mv toc.tmp $@ @@ -828,7 +838,7 @@ clean: rm -f $(GENERATED_INTERN_SCRIPT_FILES) rm -f tests/tmp.err tests/tmp.out tests/tmp.status tests/foo.txt rm -f $(PROGRAMS) fish_tests key_reader - rm -f command_list.txt toc.txt + rm -f command_list.txt command_list_toc.txt toc.txt rm -f doc_src/index.hdr doc_src/commands.hdr rm -f FISH-BUILD-VERSION-FILE if test "$(HAVE_DOXYGEN)" = 1; then \ diff --git a/doc_src/commands.hdr.in b/doc_src/commands.hdr.in index b62a6d568..c29675bd6 100644 --- a/doc_src/commands.hdr.in +++ b/doc_src/commands.hdr.in @@ -1,6 +1,15 @@ -/** \page commands Commands, functions and builtins bundled with fish -Fish ships with a large number of builtin commands, shellscript functions and external commands. These are all described below. +/** \page commands Commands bundled with fish +\htmlonly
\endhtmlonly +@command_list_toc@ +\htmlonly
\endhtmlonly + +\htmlonly +
+

Commands

+Fish ships with a large number of builtin commands, shellscript functions and external commands. These are all described below. +\endhtmlonly @command_list@ +\htmlonly
\endhtmlonly */ diff --git a/doc_src/design.hdr b/doc_src/design.hdr index f1047546e..b0b4635ff 100644 --- a/doc_src/design.hdr +++ b/doc_src/design.hdr @@ -1,5 +1,7 @@ /** \page design Design document +\htmlonly
\endhtmlonly + \section design-overview Overview This is a description of the design principles that have been used to @@ -132,3 +134,5 @@ Examples: - The language should be uniform, so that once the user understands the command/argument syntax, he will know the whole language, and be able to use tab-completion to discover new featues. */ + +\htmlonly
\endhtmlonly diff --git a/doc_src/faq.hdr b/doc_src/faq.hdr index 449c10f4f..c727dd5da 100644 --- a/doc_src/faq.hdr +++ b/doc_src/faq.hdr @@ -1,5 +1,7 @@ /** \page faq Frequently asked questions +\htmlonly +
+

Frequently Asked Questions

+ +\endhtmlonly \section faq-envvar How do I set or clear an environment variable? @@ -29,7 +36,7 @@ set -e key
-\section faq-login-cmd How do I run a command every login? What's fish's equivalent to .bashrc? +\section faq-login-cmd How do I run a command every login? What's fish's equivalent to .bashrc? Edit the file ~/.config/fish/config.fish, creating it if it does not exist. (Note the leading period.) @@ -263,3 +270,7 @@ rm -f fish mimedb fish_pager fishd fish_indent */ + +\htmlonly +
+\endhtmlonly diff --git a/doc_src/index.hdr.in b/doc_src/index.hdr.in index 25fcac640..f82f309aa 100644 --- a/doc_src/index.hdr.in +++ b/doc_src/index.hdr.in @@ -1,9 +1,12 @@ /** \mainpage Fish user documentation -\section toc Table of contents - -- Fish user documentation +\htmlonly
\endhtmlonly @toc@ +\htmlonly
\endhtmlonly + +\htmlonly +
+\endhtmlonly \section introduction Introduction @@ -1377,3 +1380,5 @@ If you have an improvement for fish, you can submit it via the mailing list or the GitHub page. */ + +\htmlonly
\endhtmlonly diff --git a/doc_src/license.hdr b/doc_src/license.hdr index 2225a0850..64bab10f0 100644 --- a/doc_src/license.hdr +++ b/doc_src/license.hdr @@ -1,5 +1,7 @@ /** \page license Licenses +\htmlonly
\endhtmlonly +

License for fish

Fish Copyright (C) 2005-2009 Axel Liljencrantz. Fish is released under @@ -1399,3 +1401,5 @@ POSSIBILITY OF SUCH DAMAGES.

*/ + +\htmlonly

\endhtmlonly diff --git a/doc_src/tutorial.hdr b/doc_src/tutorial.hdr new file mode 100644 index 000000000..d5cd69482 --- /dev/null +++ b/doc_src/tutorial.hdr @@ -0,0 +1,746 @@ +/** \page tutorial Tutorial + +\htmlonly + + + + + + +
+ +

fish tutorial

+ +

Why fish?

+ +

fish is a fully-equipped command line shell (like bash or zsh) that is smart and user-friendly. fish supports powerful features like syntax highlighting, autosuggestions, and tab completions that just work, with nothing to learn or configure. + +

If you want to make your command line more productive, more useful, and more fun, without learning a bunch of arcane syntax and configuration options, then fish might be just what you're looking for! + +

Learning fish

+ +

This tutorial assumes a basic understanding of command line shells and Unix commands, and that you have a working copy of fish. + +

If you have a strong understanding of other shells, and want to know what fish does differently, search for the magic phrase unlike other shells, which is used to call out important differences. + +

When you start fish, you should see this: + +

+Welcome to fish, the friendly interactive shell
+Type help for instructions on how to use fish
+you@hostname ~>
+
+ +

fish comes with a default prompt that shows your username, hostname, and working directory. You'll see how to change your prompt further down. From now on, we'll pretend your prompt is just a '>' to save space. + +

Running Commands

+ +

fish runs commands like other shells: you type a command, followed by its arguments. Spaces are separators: + +

+> echo hello world
+hello world
+
+ +You can include a literal space in an argument with a backslash, or by using single or double quotes: + +
+> mkdir My\ Files
+> cp ~/Some\ File 'My Files'
+> ls "My Files"
+Some File
+
+ +Commands can be chained with semicolons. + +

Getting Help

+ +fish has excellent help and man pages. Run help to open help in a web browser, and man to open it in a man page. You can also ask for help with a specific command, for example, help set to open in a web browser, or man set to see it in the terminal. + +
+> man set
+set - handle environment variables
+  Synopsis...
+
+ +

Syntax Highlighting

+You'll quickly notice that fish performs syntax highlighting as you type. Invalid commands are colored red by default: + +
+> /bin/mkd
+
+ +A command may be invalid because it does not exist, or refers to a file that you cannot execute. When the command becomes valid, it is shown in a different color: + +
+> /bin/mkdir
+
+ +fish will underline valid file paths as you type them: + +
+> cat ~/somefi
+
+ +

This tells you that there exists a file that starts with 'somefi', which is useful feedback as you type. + +

These colors, and many more, can be changed by running fish_config, or by modifying variables directly. + +

Wildcards

+ +fish supports the familiar wildcard *. To list all JPEG files: + +
+> ls *.jpg
+lena.jpg
+meena.jpg
+santa maria.jpg
+
+ +

You can include multiple wildcards: + +

+> ls l*.p*
+lena.png
+lesson.pdf
+
+ +

Especially powerful is the recursive wildcard ** which searches directories recursively: + +

+> ls /var/**.log
+/var/log/system.log
+/var/run/sntp.log
+
+ +

If that directory traversal is taking a long time, you can control-C out of it. + +

Pipes and Redirections

+ +

You can pipe between commands with the usual vertical bar: + +

+> echo hello world | wc
+           1       2      12
+
+ +

stdin and stdout can be redirected via the familiar < and >. Unlike other shells, stderr is redirected with a caret ^ + +

+> grep fish < /etc/shells > ~/output.txt ^ ~/errors.txt
+
+ +

Autosuggestions

+ +fish suggests commands as you type, and shows the suggestion to the right of the cursor, in gray. For example: + +
+> /bin/hostname
+
+ +It knows about paths and options: + +
+> grep --ignore-case
+
+ +And history too. Type a command once, and you can re-summon it by just typing a few letters: + +
+> rsync -avze ssh . myname@somelonghost.com:/some/long/path/doo/dee/doo/dee/doo
+
+ +To accept the autosuggestion, hit right arrow or Control-F. If the autosuggestion is not what you want, just ignore it. + +

Tab Completions

+ +

fish comes with a rich set of tab completions, that work "out of the box." + +

Press tab, and fish will attempt to complete the command, argument, or path: + +

+> /pri<tab> → /private/
+
+ +

If there's more than one possibility, it will list them: +

+> ~/stuff/s<tab>
+~/stuff/script.sh  (Executable, 4.8kB)  ~/stuff/sources/  (Directory)
+
+ +

Hit tab again to cycle through the possibilities. + +

fish can also complete many commands, like git branches: + +

+> git merge pr<tab> → git merge prompt_designer
+> git checkout b<tab>
+builtin_list_io_merge  (Branch)  builtin_set_color  (Branch)  busted_events  (Tag)
+
+ +Try hitting tab and see what fish can do! + +

Variables

+ +

Like other shells, a dollar sign performs variable substitution: + +

+> echo My home directory is $HOME
+My home directory is /home/tutorial
+
+ +Variable substitution also occurs in double quotes, but not single quotes: + +
+> echo "My current directory is $PWD"
+My current directory is /home/tutorial
+> echo 'My current directory is $PWD'
+My current directory is $PWD
+
+ +Unlike other shells, fish has no dedicated syntax for setting variables. Instead it has an ordinary command: set, which takes a variable name, and then its value. + +
+> set name 'Mister Noodle'
+> echo $name
+Mister Noodle
+
+ +

(Notice the quotes: without them, Mister and Noodle would have been separate arguments, and $name would have been made into a list of two elements.) + +

Unlike other shells, variables are not further split after substitution: + +

+> mkdir $name
+> ls
+Mister Noodle
+
+ +In bash, this would have created two directories "Mister" and "Noodle". In fish, it created only one: the variable had the value "Mister Noodle", so that is the argument that was passed to mkdir, spaces and all. + +

Exit Status

+ +Unlike other shells, fish stores the exit status of the last command in $status instead of $?. + +
+> false
+> echo $status
+1
+
+ +Zero is considered success, and non-zero is failure. + +

Exports (Environment Variables)

+ +Unlike other shells, fish does not have an export command. Instead, a variable is exported via an option to set, either --export or just -x. + +
+> set -x MyVariable SomeValue
+> env | grep MyVariable
+MyVariable=SomeValue
+
+ +You can erase a variable with -e or --erase +
+> set -e MyVariable
+> env | grep MyVariable
+(no output)
+
+ +

Lists

+ +

The set command above used quotes to ensure that Mister Noodle was one argument. If it had been two arguments, then name would have been a list of length 2. In fact, all variables in fish are really lists, that can contain any number of values, or none at all. + +

Some variables, like $PWD, only have one value. By convention, we talk about that variable's value, but we really mean its first (and only) value. + +

Other variables, like $PATH, really do have multiple values. During variable expansion, the variable expands to become multiple arguments: + +

+> echo $PATH
+/usr/bin /bin /usr/sbin /sbin /usr/local/bin
+
+ +

Lists cannot contain other lists: there is no recursion. A variable is a list of strings, full stop. + +

Get the length of a list with count: + +

+> count $PATH
+5
+
+ +You can append (or prepend) to a list by setting the list to itself, with some additional arguments. Here we append /usr/local/bin to $PATH: + +
+> set PATH $PATH /usr/local/bin
+
+ + +You can access individual elements with square brackets. Indexing starts at 1 from the beginning, and -1 from the end: +
+> echo $PATH
+/usr/bin /bin /usr/sbin /sbin /usr/local/bin
+> echo $PATH[1]
+/usr/bin
+> echo $PATH[-1]
+/usr/local/bin
+
+ +You can also access ranges of elements, known as "slices:" + +
+> echo $PATH[1..2]
+/usr/bin /bin
+> echo $PATH[-1..2]
+/usr/local/bin /sbin /usr/sbin /bin
+
+ +You can iterate over a list (or a slice) with a for loop: + +
+> for val in $PATH
+        echo "entry: $val"
+  end
+entry: usr/bin/
+entry: /bin
+entry: /usr/sbin
+entry: /sbin
+entry: /usr/local/bin
+
+ + +

Command Substitutions

+ +Command substitutions use the output of one command as an argument to another. Unlike other shells, fish does not use backticks ` for command substitutions. Instead, it uses parentheses: + +
+> echo In (pwd), running (uname)
+In /home/tutorial, running FreeBSD
+
+ +A common idiom is to capture the output of a command in a variable: + +
+> set os (uname)
+> echo $os
+Linux
+
+ +Command substitutions are not expanded within quotes. Instead, you can temporarily close the quotes, add the command substitution, and reopen them, all in the same argument: + +
+> touch "testing_"(date +%s)".txt"
+> ls *.txt
+testing_1360099791.txt
+
+ +

Combiners (And, Or, Not)

+ +Unlike other shells, fish does not have special syntax like && or || to combine commands. Instead it has commands and, or, and not. + +
+> cp file1.txt file1_bak.txt; and echo "Backup successful"; or echo "Backup failed"
+Backup failed
+
+ +

Conditionals (If, Else, Switch)

+ +Use if, else if, and else to conditionally execute code, based on the exit status of a command. + +
+if grep fish /etc/shells
+        echo Found fish
+else if grep bash /etc/shells
+        echo Found bash
+else
+        echo Got nothing
+end
+
+ +There is also a switch command: + +
+switch (uname)
+        case Linux
+                echo Hi Tux!
+        case Darwin
+                echo Hi Hexley!
+        case FreeBSD NetBSD DragonFly
+                echo Hi Beastie!
+        case '*'
+                echo Hi, stranger!
+end
+
+ +Note that case does not fall through, and can accept multiple arguments or (quoted) wildcards. + +

Functions

+ +A fish function is a list of commands, which may optionally take arguments. Unlike other shells, arguments are not passed in "numbered variables" like $1, but instead in a single list $argv. To create a function, use the function builtin: + +
+> function say_hello
+         echo Hello $argv
+  end
+> say_hello
+Hello
+> say_hello everybody!
+Hello everybody!
+
+ +

Unlike other shells, fish does not have aliases or special prompt syntax. Functions take their place. + +

You can list the names of all functions with the functions keyword (note the plural!). fish starts out with a number of functions: + +

+> functions
+alias, cd, delete-or-exit, dirh, dirs, down-or-search, eval, export, fish_command_not_found_setup, fish_config, fish_default_key_bindings, fish_prompt, fish_right_prompt, fish_sigtrap_handler, fish_update_completions, funced, funcsave, grep, help, history, isatty, ls, man, math, nextd, nextd-or-forward-word, open, popd, prevd, prevd-or-backward-word, prompt_pwd, psub, pushd, seq, setenv, sgrep, trap, type, umask, up-or-search, vared
+
+ +

You can see the source for any function by passing its name to functions: + +

+> functions ls
+function ls --description 'List contents of directory'
+        command ls -G $argv
+end
+
+ +

Loops

+ +While loops: + +
+> while true
+        echo "Loop forever"
+end
+Loop forever
+Loop forever
+Loop forever
+...
+
+ +For loops can be used to iterate over a list. For example, a list of files: + +
+> for file in *.txt
+        cp $file $file.bak
+end
+
+ +Iterating over a list of numbers can be done with `seq`: + +
+> for x in (seq 5)
+        touch file_$x.txt
+end
+
+ + +

Prompt

+ +Unlike other shells, there is no prompt variable like PS1. To display your prompt, fish executes a function with the name fish_prompt, and its output is used as the prompt. + +You can define your own prompt: +
+> function fish_prompt
+        echo "New Prompt % "
+  end
+New Prompt %  
+
+
+ +Multiple lines are OK. Colors can be set via set_color, passing it named ANSI colors, or hex RGB values: + +
+> function fish_prompt
+        set_color purple
+        date "+%m/%d/%y"
+        set_color FF0
+        echo (pwd) '>'
+        set_color normal
+  end
+02/06/13
+/home/tutorial > 
+
+
+ +

You can choose among some sample prompts by running fish_config prompt. fish also supports RPROMPT through fish_right_prompt. + +

$PATH

+ +$PATH is an environment variable containing the directories in which fish searches for commands. Instead of separating entries with a colon, $PATH is a list. You can modify $PATH in a few ways: + +

    +
  1. By modifying the $fish_user_paths variable, which is automatically appended to $PATH. For example, to permanently add /usr/local/bin to your $PATH, you could write: + +
    +> set -U fish_user_paths $fish_user_paths /usr/local/bin
    +
    + + +
  2. Directly in config.fish (see below).
  3. +
+ +

Startup (Where's .bashrc?)

+ +

fish starts by executing commands in ~/.config/fish/config.fish. You can create it if it does not exist. + +

It is possible to directly create functions and variables in config.fish file, using the commands shown above. For example: + +

+> cat ~/.config/fish/config.fish
+
+set -x PATH $PATH /sbin/
+
+function ll
+    ls -lh $argv
+end
+
+ +

However, it is more common and efficient to use autoloading functions and universal variables. + +

Autoloading Functions

+ +

When fish encounters a command, it attempts to autoload a function for that command, by looking for a file with the name of that command in ~/.config/fish/functions/. + +

For example, if you wanted to have a function ll, you would add a text file ll.fish to ~/.config/fish/functions: + +

+> cat ~/.config/fish/functions/ll.fish
+function ll
+        ls -lh $argv
+end
+
+ +This is the preferred way to define your prompt as well: + +
+> cat ~/.config/fish/functions/fish_prompt.fish
+function fish_prompt
+        echo (pwd) '> '
+end
+
+ +

See the documentation for funced and funcsave for ways to create these files automatically. + +

Universal Variables

+ +

A universal variable is a variable whose value is shared across all instances of fish, now and in the future - even after a reboot. You can make a variable universal with set -U: + +

+> set -U EDITOR vim
+
+ +Now in another shell: + +
+> echo $EDITOR
+vim
+
+ +

Ready for more?

+ +

If you want to learn more about fish, there is lots of detailed documentation, an official mailing list, the IRC channel #fish on irc.oftc.net, and the github page. + +

+ \endhtmlonly diff --git a/user_doc.head.html b/user_doc.head.html index 7ac670ce8..958a96910 100644 --- a/user_doc.head.html +++ b/user_doc.head.html @@ -2,41 +2,158 @@ fish user documentation - +
- fish home + fish shell | - Main documentation page + Documentation | -Design document + Tutorial +| +Design | Commands | From 09ff1e7af00bb168bdfa296bcafb7f034b5b6da1 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 5 Oct 2013 01:56:25 -0700 Subject: [PATCH 169/170] Update make_tarball.sh to work on Darwin --- build_tools/make_tarball.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build_tools/make_tarball.sh b/build_tools/make_tarball.sh index 2c3a0ac1b..f16171d14 100755 --- a/build_tools/make_tarball.sh +++ b/build_tools/make_tarball.sh @@ -33,14 +33,16 @@ rm -f "$path" "$path".gz git archive --format=tar --prefix="$prefix"/ master > "$path" # tarball out the documentation, generate a configure script and version file -autoreconf +# Don't use autoreconf since it invokes commands that may not be installed, like aclocal +# Don't run autoheader since configure.ac runs it. autoconf is enough. +autoconf ./configure --with-doxygen make user_doc share/man echo $VERSION > version cd /tmp rm -f "$prefix" ln -s "$wd" "$prefix" -TAR_APPEND="gnutar --append --file=$path --mtime=now --owner=root --group=root --mode=g+w,a+rX" +TAR_APPEND="gnutar --append --file=$path --mtime=now --owner=0 --group=0 --mode=g+w,a+rX" $TAR_APPEND --no-recursion "$prefix"/user_doc $TAR_APPEND "$prefix"/user_doc/html "$prefix"/share/man $TAR_APPEND "$prefix"/version From fab7299d49492ce548d4ceed66d3acbd05dd99c7 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 5 Oct 2013 12:13:16 -0700 Subject: [PATCH 170/170] Replace nextd/prevd
s with \code

---
 doc_src/nextd.txt | 4 +++-
 doc_src/prevd.txt | 4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/doc_src/nextd.txt b/doc_src/nextd.txt
index dba94ce02..297063af9 100644
--- a/doc_src/nextd.txt
+++ b/doc_src/nextd.txt
@@ -12,7 +12,8 @@ directory history is also displayed.
 
 \subsection nextd-example Example
 
-
cd /usr/src
+\code
+cd /usr/src
 # Working directory is now /usr/src
 cd /usr/src/fish-shell
 # Working directory is now /usr/src/fish-shell
@@ -20,3 +21,4 @@ prevd
 # Working directory is now /usr/src
 nextd
 # Working directory is now /usr/src/fish-shell
+\endcode diff --git a/doc_src/prevd.txt b/doc_src/prevd.txt index b72fc3752..e49faff22 100644 --- a/doc_src/prevd.txt +++ b/doc_src/prevd.txt @@ -14,7 +14,8 @@ history is also displayed. \subsection prevd-example Example -
cd /usr/src
+\code
+cd /usr/src
 # Working directory is now /usr/src
 cd /usr/src/fish-shell
 # Working directory is now /usr/src/fish-shell
@@ -22,3 +23,4 @@ prevd
 # Working directory is now /usr/src
 nextd
 # Working directory is now /usr/src/fish-shell
+\endcode