mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
Merge remote-tracking branch 'fishfish/master'
This commit is contained in:
commit
c0e60963c1
14 changed files with 88 additions and 26 deletions
|
@ -337,8 +337,7 @@ prof:
|
||||||
|
|
||||||
user_doc: $(HDR_FILES_SRC) Doxyfile.user user_doc.head.html $(HELP_SRC)
|
user_doc: $(HDR_FILES_SRC) Doxyfile.user user_doc.head.html $(HELP_SRC)
|
||||||
$(MAKE) doc.h $(HDR_FILES)
|
$(MAKE) doc.h $(HDR_FILES)
|
||||||
- doxygen Doxyfile.user
|
- doxygen Doxyfile.user && touch user_doc
|
||||||
touch user_doc
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -932,11 +931,12 @@ clean:
|
||||||
rm -f $(GENERATED_INTERN_SCRIPT_FILES)
|
rm -f $(GENERATED_INTERN_SCRIPT_FILES)
|
||||||
rm -f tests/tmp.err tests/tmp.out tests/tmp.status tests/foo.txt
|
rm -f tests/tmp.err tests/tmp.out tests/tmp.status tests/foo.txt
|
||||||
rm -f $(PROGRAMS) fish_tests tokenizer_test key_reader
|
rm -f $(PROGRAMS) fish_tests tokenizer_test key_reader
|
||||||
|
rm -f command_list.txt toc.txt
|
||||||
rm -f share/config.fish etc/config.fish doc_src/index.hdr doc_src/commands.hdr
|
rm -f share/config.fish etc/config.fish doc_src/index.hdr doc_src/commands.hdr
|
||||||
rm -f fish-@PACKAGE_VERSION@.tar
|
rm -f fish-@PACKAGE_VERSION@.tar
|
||||||
rm -f fish-@PACKAGE_VERSION@.tar.gz
|
rm -f fish-@PACKAGE_VERSION@.tar.gz
|
||||||
rm -f fish-@PACKAGE_VERSION@.tar.bz2
|
rm -f fish-@PACKAGE_VERSION@.tar.bz2
|
||||||
rm -rf doc;
|
rm -rf doc user_doc share/man;
|
||||||
rm -rf fish-@PACKAGE_VERSION@
|
rm -rf fish-@PACKAGE_VERSION@
|
||||||
rm -f $(TRANSLATIONS)
|
rm -f $(TRANSLATIONS)
|
||||||
test ! -d "$(XSEL)" || make -C $(XSEL) clean
|
test ! -d "$(XSEL)" || make -C $(XSEL) clean
|
||||||
|
|
|
@ -627,7 +627,7 @@ static int builtin_set( parser_t &parser, wchar_t **argv )
|
||||||
if( erase )
|
if( erase )
|
||||||
{
|
{
|
||||||
append_format(stderr_buffer,
|
append_format(stderr_buffer,
|
||||||
_(L"%ls: Erase needs a variable name\n%ls\n"),
|
_(L"%ls: Erase needs a variable name\n"),
|
||||||
argv[0] );
|
argv[0] );
|
||||||
|
|
||||||
builtin_print_help( parser, argv[0], stderr_buffer );
|
builtin_print_help( parser, argv[0], stderr_buffer );
|
||||||
|
|
|
@ -555,7 +555,7 @@ wcstring wsetlocale(int category, const wchar_t *locale)
|
||||||
{
|
{
|
||||||
|
|
||||||
char *lang = NULL;
|
char *lang = NULL;
|
||||||
if (locale && wcscmp(locale,L"")){
|
if (locale){
|
||||||
lang = wcs2str( locale );
|
lang = wcs2str( locale );
|
||||||
}
|
}
|
||||||
char * res = setlocale(category,lang);
|
char * res = setlocale(category,lang);
|
||||||
|
@ -1943,9 +1943,12 @@ void configure_thread_assertions_for_testing(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notice when we've forked */
|
/* Notice when we've forked */
|
||||||
static pid_t initial_pid;
|
static pid_t initial_pid = 0;
|
||||||
|
|
||||||
bool is_forked_child(void) {
|
bool is_forked_child(void) {
|
||||||
|
/* Just bail if nobody's called setup_fork_guards - e.g. fishd */
|
||||||
|
if (! initial_pid) return false;
|
||||||
|
|
||||||
bool is_child_of_fork = (getpid() != initial_pid);
|
bool is_child_of_fork = (getpid() != initial_pid);
|
||||||
if (is_child_of_fork) {
|
if (is_child_of_fork) {
|
||||||
printf("Uh-oh: %d\n", getpid());
|
printf("Uh-oh: %d\n", getpid());
|
||||||
|
|
13
env.cpp
13
env.cpp
|
@ -901,8 +901,7 @@ int env_set(const wcstring &key, const wchar_t *val, int var_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->val = val;
|
entry->val = val;
|
||||||
|
node->env[key] = entry;
|
||||||
node->env.insert(std::pair<wcstring, var_entry_t*>(key, entry));
|
|
||||||
|
|
||||||
if( entry->exportv )
|
if( entry->exportv )
|
||||||
{
|
{
|
||||||
|
@ -1397,7 +1396,8 @@ static void get_exported( const env_node_t *n, std::map<wcstring, wcstring> &h )
|
||||||
var_entry_t *val_entry = iter->second;
|
var_entry_t *val_entry = iter->second;
|
||||||
if( val_entry->exportv && (val_entry->val != ENV_NULL ) )
|
if( val_entry->exportv && (val_entry->val != ENV_NULL ) )
|
||||||
{
|
{
|
||||||
h.insert(std::pair<wcstring, wcstring>(key, val_entry->val));
|
// Don't use std::map::insert here, since we need to overwrite existing values from previous scopes
|
||||||
|
h[key] = val_entry->val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1455,12 +1455,11 @@ static void update_export_array_if_necessary(bool recalc) {
|
||||||
const wcstring &key = uni.at(i);
|
const wcstring &key = uni.at(i);
|
||||||
const wchar_t *val = env_universal_get( key.c_str() );
|
const wchar_t *val = env_universal_get( key.c_str() );
|
||||||
|
|
||||||
std::map<wcstring, wcstring>::iterator result = vals.find( key );
|
if (wcscmp( val, ENV_NULL)) {
|
||||||
if( wcscmp( val, ENV_NULL) && ( result == vals.end() ) )
|
// Note that std::map::insert does NOT overwrite a value already in the map,
|
||||||
{
|
// which we depend on here
|
||||||
vals.insert(std::pair<wcstring, wcstring>(key, val));
|
vals.insert(std::pair<wcstring, wcstring>(key, val));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> local_export_buffer;
|
std::vector<std::string> local_export_buffer;
|
||||||
|
|
|
@ -555,7 +555,7 @@ void env_universal_common_set( const wchar_t *key, const wchar_t *val, int expor
|
||||||
entry->val = val;
|
entry->val = val;
|
||||||
env_universal_common_remove( key );
|
env_universal_common_remove( key );
|
||||||
|
|
||||||
env_universal_var.insert( std::pair<wcstring, var_uni_entry_t*>(key, entry));
|
env_universal_var[key] = entry;
|
||||||
if( callback )
|
if( callback )
|
||||||
{
|
{
|
||||||
callback( exportv?SET_EXPORT:SET, key, val );
|
callback( exportv?SET_EXPORT:SET, key, val );
|
||||||
|
|
|
@ -103,6 +103,28 @@ static wcstring apply_working_directory(const wcstring &path, const wcstring &wo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Determine if the filesystem containing the given fd is case insensitive. */
|
||||||
|
typedef std::map<wcstring, bool> case_sensitivity_cache_t;
|
||||||
|
bool fs_is_case_insensitive(const wcstring &path, int fd, case_sensitivity_cache_t &case_sensitivity_cache)
|
||||||
|
{
|
||||||
|
/* If _PC_CASE_SENSITIVE is not defined, assume case sensitive */
|
||||||
|
bool result = false;
|
||||||
|
#ifdef _PC_CASE_SENSITIVE
|
||||||
|
/* Try the cache first */
|
||||||
|
case_sensitivity_cache_t::iterator cache = case_sensitivity_cache.find(path);
|
||||||
|
if (cache != case_sensitivity_cache.end()) {
|
||||||
|
/* Use the cached value */
|
||||||
|
result = cache->second;
|
||||||
|
} else {
|
||||||
|
/* Ask the system. A -1 value means error (so assume case sensitive), a 1 value means case sensitive, and a 0 value means case insensitive */
|
||||||
|
long ret = fpathconf(fd, _PC_CASE_SENSITIVE);
|
||||||
|
result = (ret == 0);
|
||||||
|
case_sensitivity_cache[path] = result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* Tests whether the specified string cpath is the prefix of anything we could cd to. directories is a list of possible parent directories (typically either the working directory, or the cdpath). This does I/O!
|
/* Tests whether the specified string cpath is the prefix of anything we could cd to. directories is a list of possible parent directories (typically either the working directory, or the cdpath). This does I/O!
|
||||||
*/
|
*/
|
||||||
bool is_potential_path(const wcstring &const_path, const wcstring_list_t &directories, bool require_dir, wcstring *out_path)
|
bool is_potential_path(const wcstring &const_path, const wcstring_list_t &directories, bool require_dir, wcstring *out_path)
|
||||||
|
@ -161,6 +183,9 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct
|
||||||
/* Don't test the same path multiple times, which can happen if the path is absolute and the CDPATH contains multiple entries */
|
/* Don't test the same path multiple times, which can happen if the path is absolute and the CDPATH contains multiple entries */
|
||||||
std::set<wcstring> checked_paths;
|
std::set<wcstring> checked_paths;
|
||||||
|
|
||||||
|
/* Keep a cache of which paths / filesystems are case sensitive */
|
||||||
|
case_sensitivity_cache_t case_sensitivity_cache;
|
||||||
|
|
||||||
for (size_t wd_idx = 0; wd_idx < directories.size() && ! result; wd_idx++) {
|
for (size_t wd_idx = 0; wd_idx < directories.size() && ! result; wd_idx++) {
|
||||||
const wcstring &wd = directories.at(wd_idx);
|
const wcstring &wd = directories.at(wd_idx);
|
||||||
|
|
||||||
|
@ -200,12 +225,23 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct
|
||||||
// We opened the dir_name; look for a string where the base name prefixes it
|
// We opened the dir_name; look for a string where the base name prefixes it
|
||||||
wcstring ent;
|
wcstring ent;
|
||||||
|
|
||||||
|
// Check if we're case insensitive
|
||||||
|
bool case_insensitive = fs_is_case_insensitive(dir_name, dirfd(dir), case_sensitivity_cache);
|
||||||
|
|
||||||
// Don't ask for the is_dir value unless we care, because it can cause extra filesystem acces */
|
// Don't ask for the is_dir value unless we care, because it can cause extra filesystem acces */
|
||||||
bool is_dir = false;
|
bool is_dir = false;
|
||||||
while (wreaddir_resolving(dir, dir_name, ent, require_dir ? &is_dir : NULL))
|
while (wreaddir_resolving(dir, dir_name, ent, require_dir ? &is_dir : NULL))
|
||||||
{
|
{
|
||||||
// TODO: support doing the right thing on case-insensitive filesystems like HFS+
|
|
||||||
if (string_prefixes_string(base_name, ent) && (! require_dir || is_dir))
|
/* Determine which function to call to check for prefixes */
|
||||||
|
bool (*prefix_func)(const wcstring &, const wcstring &);
|
||||||
|
if (case_insensitive) {
|
||||||
|
prefix_func = string_prefixes_string_case_insensitive;
|
||||||
|
} else {
|
||||||
|
prefix_func = string_prefixes_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefix_func(base_name, ent) && (! require_dir || is_dir))
|
||||||
{
|
{
|
||||||
result = true;
|
result = true;
|
||||||
if (out_path) {
|
if (out_path) {
|
||||||
|
@ -213,7 +249,9 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct
|
||||||
|
|
||||||
out_path->clear();
|
out_path->clear();
|
||||||
const wcstring path_base = wdirname(const_path);
|
const wcstring path_base = wdirname(const_path);
|
||||||
if (string_prefixes_string(path_base, const_path)) {
|
|
||||||
|
|
||||||
|
if (prefix_func(path_base, const_path)) {
|
||||||
out_path->append(path_base);
|
out_path->append(path_base);
|
||||||
if (! string_suffixes_string(L"/", *out_path))
|
if (! string_suffixes_string(L"/", *out_path))
|
||||||
out_path->push_back(L'/');
|
out_path->push_back(L'/');
|
||||||
|
|
|
@ -1607,7 +1607,7 @@ static int handle_completions( const std::vector<completion_t> &comp )
|
||||||
0,
|
0,
|
||||||
0 );
|
0 );
|
||||||
|
|
||||||
len = &buff[data->buff_pos]-prefix_start+1;
|
len = &buff[data->buff_pos]-prefix_start;
|
||||||
|
|
||||||
if( len <= PREFIX_MAX_LEN )
|
if( len <= PREFIX_MAX_LEN )
|
||||||
{
|
{
|
||||||
|
|
|
@ -327,6 +327,10 @@ static int room_for_usec(struct stat *st)
|
||||||
static void s_save_status( screen_t *s)
|
static void s_save_status( screen_t *s)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// PCA Let's not do this futimes stuff, because sudo dumbly uses the
|
||||||
|
// tty's ctime as part of its tty_tickets feature
|
||||||
|
// Disabling this should fix https://github.com/fish-shell/fish-shell/issues/122
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
This futimes call tries to trick the system into using st_mtime
|
This futimes call tries to trick the system into using st_mtime
|
||||||
as a tampering flag. This of course only works on systems where
|
as a tampering flag. This of course only works on systems where
|
||||||
|
@ -354,6 +358,7 @@ static void s_save_status( screen_t *s)
|
||||||
*/
|
*/
|
||||||
futimes( 1, t );
|
futimes( 1, t );
|
||||||
futimes( 2, t );
|
futimes( 2, t );
|
||||||
|
#endif
|
||||||
|
|
||||||
fstat( 1, &s->prev_buff_1 );
|
fstat( 1, &s->prev_buff_1 );
|
||||||
fstat( 2, &s->prev_buff_2 );
|
fstat( 2, &s->prev_buff_2 );
|
||||||
|
|
|
@ -2,7 +2,11 @@ function __fish_complete_command --description 'Complete using all available com
|
||||||
set -l ctoken (commandline -ct)
|
set -l ctoken (commandline -ct)
|
||||||
switch $ctoken
|
switch $ctoken
|
||||||
case '*=*'
|
case '*=*'
|
||||||
set ctoken (echo $ctoken | sed 's/=/\n/')
|
# 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
|
||||||
|
set ctoken (echo $ctoken | sed 's/=/\\
|
||||||
|
/')
|
||||||
printf '%s\n' $ctoken[1]=(complete -C$ctoken[2])
|
printf '%s\n' $ctoken[1]=(complete -C$ctoken[2])
|
||||||
case '*'
|
case '*'
|
||||||
complete -C$ctoken
|
complete -C$ctoken
|
||||||
|
|
|
@ -5,7 +5,11 @@ function __fish_complete_lpr_option --description 'Complete lpr option'
|
||||||
set -l IFS =
|
set -l IFS =
|
||||||
echo $optstr | read -l opt val
|
echo $optstr | read -l opt val
|
||||||
set -l descr
|
set -l descr
|
||||||
for l in (lpoptions -l ^ /dev/null | grep $opt | sed 's+\(.*\)/\(.*\):\s*\(.*\)$+\2 \3+; s/ /\n/g;')
|
# 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
|
||||||
|
for l in (lpoptions -l ^ /dev/null | grep $opt | sed 's+\(.*\)/\(.*\):\s*\(.*\)$+\2 \3+; s/ /\\
|
||||||
|
/g;')
|
||||||
if not set -q descr[1]
|
if not set -q descr[1]
|
||||||
set descr $l
|
set descr $l
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -23,7 +23,7 @@ function __fish_print_help --description "Print help message for the specified f
|
||||||
set -l sed_cmd -e $cmd1 -e $cmd2 -e $cmd3
|
set -l sed_cmd -e $cmd1 -e $cmd2 -e $cmd3
|
||||||
|
|
||||||
# Render help output, save output into the variable 'help'
|
# Render help output, save output into the variable 'help'
|
||||||
set -l help (nroff -man $__fish_datadir/man/$item.1)
|
set -l help (nroff -man $__fish_datadir/man/man1/$item.1)
|
||||||
set -l lines (count $help)
|
set -l lines (count $help)
|
||||||
|
|
||||||
# Print an empty line first
|
# Print an empty line first
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
function __fish_print_make_targets
|
function __fish_print_make_targets
|
||||||
set files Makefile makefile GNUmakefile
|
set files Makefile makefile GNUmakefile
|
||||||
sgrep -h -E '^[^#%=$[:space:]][^#%=$]*:([^=]|$)' $files | cut -d ":" -f 1 | sed -e 's/^ *//;s/ *$//;s/ */\n/g' ^/dev/null
|
# 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/ */\\
|
||||||
|
/g' ^/dev/null
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,7 +17,11 @@ function alias --description "Legacy function for creating shellscript functions
|
||||||
echo "Fish implements aliases using functions. Use 'functions' builtin to see list of functions and 'functions function_name' to see function definition, type 'help alias' for more information."
|
echo "Fish implements aliases using functions. Use 'functions' builtin to see list of functions and 'functions function_name' to see function definition, type 'help alias' for more information."
|
||||||
return 1
|
return 1
|
||||||
case 1
|
case 1
|
||||||
set -l tmp (echo $argv|sed -e "s/\([^=]\)=/\1\n/")
|
# 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
|
||||||
|
set -l tmp (echo $argv|sed -e "s/\([^=]\)=/\1\\
|
||||||
|
/")
|
||||||
set name $tmp[1]
|
set name $tmp[1]
|
||||||
set body $tmp[2]
|
set body $tmp[2]
|
||||||
|
|
||||||
|
|
|
@ -753,7 +753,8 @@ def parse_and_output_man_pages(paths, output_directory, show_progress):
|
||||||
# Pad on the right with spaces so we overwrite whatever we wrote last time
|
# Pad on the right with spaces so we overwrite whatever we wrote last time
|
||||||
padded_progress_str = progress_str.ljust(last_progress_string_length)
|
padded_progress_str = progress_str.ljust(last_progress_string_length)
|
||||||
last_progress_string_length = len(progress_str)
|
last_progress_string_length = len(progress_str)
|
||||||
sys.stdout.write("\r\r{0} {1}".format(padded_progress_str, chr(27)))
|
sys.stdout.write("\r{0} {1}\r".format(padded_progress_str, chr(27)))
|
||||||
|
sys.stdout.flush();
|
||||||
try:
|
try:
|
||||||
if parse_manpage_at_path(manpage_path, output_directory):
|
if parse_manpage_at_path(manpage_path, output_directory):
|
||||||
successful_count += 1
|
successful_count += 1
|
||||||
|
|
Loading…
Reference in a new issue