mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-31 12:21:19 -03:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
708d6b6911 | ||
|
|
c3dddee804 | ||
|
|
e468b71459 | ||
|
|
41f87e82a8 | ||
|
|
c9a409dcf3 | ||
|
|
0297e5a105 | ||
|
|
5996962749 | ||
|
|
8d32eb62ae | ||
|
|
446f5d6134 |
@@ -1,3 +1,11 @@
|
|||||||
|
# fish 2.5.0 (released February 3, 2017)
|
||||||
|
|
||||||
|
There are no major changes between 2.5b1 and 2.5.0. If you are upgrading from version 2.4.0 or before, please also review the release notes for 2.5b1 (included below).
|
||||||
|
|
||||||
|
## Notable fixes and improvements
|
||||||
|
|
||||||
|
- The Home, End, Insert, Delete, Page Up and Page Down keys work in Vi-style key bindings (#3731).
|
||||||
|
|
||||||
# fish 2.5b1 (released January 14, 2017)
|
# fish 2.5b1 (released January 14, 2017)
|
||||||
|
|
||||||
## Platform Changes
|
## Platform Changes
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2.4.900</string>
|
<string>2.5.0</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>0.1</string>
|
<string>0.1</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
|
|||||||
@@ -197,7 +197,7 @@
|
|||||||
#define PACKAGE_NAME "fish"
|
#define PACKAGE_NAME "fish"
|
||||||
|
|
||||||
/* Define to the full name and version of this package. */
|
/* Define to the full name and version of this package. */
|
||||||
#define PACKAGE_STRING "fish 2.5b1"
|
#define PACKAGE_STRING "fish 2.5.0"
|
||||||
|
|
||||||
/* Define to the one symbol short name of this package. */
|
/* Define to the one symbol short name of this package. */
|
||||||
#define PACKAGE_TARNAME "fish"
|
#define PACKAGE_TARNAME "fish"
|
||||||
@@ -206,7 +206,7 @@
|
|||||||
#define PACKAGE_URL ""
|
#define PACKAGE_URL ""
|
||||||
|
|
||||||
/* Define to the version of this package. */
|
/* Define to the version of this package. */
|
||||||
#define PACKAGE_VERSION "2.5b1"
|
#define PACKAGE_VERSION "2.5.0"
|
||||||
|
|
||||||
/* The size of `wchar_t', as computed by sizeof. */
|
/* The size of `wchar_t', as computed by sizeof. */
|
||||||
#define SIZEOF_WCHAR_T 4
|
#define SIZEOF_WCHAR_T 4
|
||||||
|
|||||||
@@ -230,14 +230,6 @@ function __fish_config_interactive -d "Initializations that should be performed
|
|||||||
and return
|
and return
|
||||||
printf \e\]7\;file://\%s\%s\a (hostname) (echo -n $PWD | __fish_urlencode)
|
printf \e\]7\;file://\%s\%s\a (hostname) (echo -n $PWD | __fish_urlencode)
|
||||||
end
|
end
|
||||||
if test "$TERM_PROGRAM" = "Apple_Terminal"
|
|
||||||
# Suppress duplicative title display on Terminal.app
|
|
||||||
if not functions -q fish_title
|
|
||||||
echo -n \e\]0\;\a # clear existing title
|
|
||||||
function fish_title -d 'no-op terminal title'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
__update_cwd_osc # Run once because we might have already inherited a PWD from an old tab
|
__update_cwd_osc # Run once because we might have already inherited a PWD from an old tab
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ function __fish_shared_key_bindings -d "Bindings shared between emacs and vi mod
|
|||||||
bind $argv \eOC forward-char
|
bind $argv \eOC forward-char
|
||||||
bind $argv \eOD backward-char
|
bind $argv \eOD backward-char
|
||||||
|
|
||||||
|
bind $argv -k ppage beginning-of-history
|
||||||
|
bind $argv -k npage end-of-history
|
||||||
|
|
||||||
# Interaction with the system clipboard.
|
# Interaction with the system clipboard.
|
||||||
bind $argv \cx fish_clipboard_copy
|
bind $argv \cx fish_clipboard_copy
|
||||||
bind $argv \cv fish_clipboard_paste
|
bind $argv \cv fish_clipboard_paste
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ function edit_command_buffer --description 'Edit the command buffer in an extern
|
|||||||
if test $status -eq 0 -a -s $f
|
if test $status -eq 0 -a -s $f
|
||||||
# Set the command to the output of the edited command and move the cursor to the
|
# Set the command to the output of the edited command and move the cursor to the
|
||||||
# end of the edited command.
|
# end of the edited command.
|
||||||
commandline -r (cat $f)
|
commandline -r -- (cat $f)
|
||||||
commandline -C 999999
|
commandline -C 999999
|
||||||
else
|
else
|
||||||
echo
|
echo
|
||||||
|
|||||||
@@ -51,7 +51,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.
|
# OS X SnowLeopard doesn't have these keys. Don't show an annoying error message.
|
||||||
bind $argv -k home beginning-of-line 2>/dev/null
|
bind $argv -k home beginning-of-line 2>/dev/null
|
||||||
bind $argv -k end end-of-line 2>/dev/null
|
bind $argv -k end end-of-line 2>/dev/null
|
||||||
bind $argv \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-delete
|
bind $argv \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-ctrl-delete
|
||||||
|
|
||||||
bind $argv \ca beginning-of-line
|
bind $argv \ca beginning-of-line
|
||||||
bind $argv \ce end-of-line
|
bind $argv \ce end-of-line
|
||||||
@@ -72,8 +72,6 @@ function fish_default_key_bindings -d "Default (Emacs-like) key bindings for fis
|
|||||||
bind $argv \ef forward-word
|
bind $argv \ef forward-word
|
||||||
bind $argv \e\[1\;5C forward-word
|
bind $argv \e\[1\;5C forward-word
|
||||||
bind $argv \e\[1\;5D backward-word
|
bind $argv \e\[1\;5D backward-word
|
||||||
bind $argv -k ppage beginning-of-history
|
|
||||||
bind $argv -k npage end-of-history
|
|
||||||
bind $argv \e\< beginning-of-buffer
|
bind $argv \e\< beginning-of-buffer
|
||||||
bind $argv \e\> end-of-buffer
|
bind $argv \e\> end-of-buffer
|
||||||
|
|
||||||
|
|||||||
@@ -110,10 +110,17 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish'
|
|||||||
bind e forward-char forward-word backward-char
|
bind e forward-char forward-word backward-char
|
||||||
bind E forward-bigword backward-char
|
bind E forward-bigword backward-char
|
||||||
|
|
||||||
bind x delete-char
|
# OS X SnowLeopard doesn't have these keys. Don't show an annoying error message.
|
||||||
bind X backward-delete-char
|
# Vi/Vim doesn't support these keys in insert mode but that seems silly so we do so anyway.
|
||||||
|
bind -M insert -k home beginning-of-line 2>/dev/null
|
||||||
|
bind -M default -k home beginning-of-line 2>/dev/null
|
||||||
|
bind -M insert -k end end-of-line 2>/dev/null
|
||||||
|
bind -M default -k end end-of-line 2>/dev/null
|
||||||
|
|
||||||
bind -k dc delete-char
|
bind -M default x delete-char
|
||||||
|
bind -M default X backward-delete-char
|
||||||
|
bind -M insert -k dc delete-char
|
||||||
|
bind -M default -k dc delete-char
|
||||||
|
|
||||||
# Backspace deletes a char in insert mode, but not in normal/default mode.
|
# Backspace deletes a char in insert mode, but not in normal/default mode.
|
||||||
bind -M insert -k backspace backward-delete-char
|
bind -M insert -k backspace backward-delete-char
|
||||||
@@ -122,7 +129,8 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish'
|
|||||||
bind -M default \ch backward-char
|
bind -M default \ch backward-char
|
||||||
bind -M insert \x7f backward-delete-char
|
bind -M insert \x7f backward-delete-char
|
||||||
bind -M default \x7f backward-char
|
bind -M default \x7f backward-char
|
||||||
bind \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-delete
|
bind -M insert \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-ctrl-delete
|
||||||
|
bind -M default \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-ctrl-delete
|
||||||
|
|
||||||
bind dd kill-whole-line
|
bind dd kill-whole-line
|
||||||
bind D kill-line
|
bind D kill-line
|
||||||
|
|||||||
@@ -810,11 +810,11 @@ int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||||||
expression *expr = test_parser::parse_args(args, err, program_name);
|
expression *expr = test_parser::parse_args(args, err, program_name);
|
||||||
if (!expr) {
|
if (!expr) {
|
||||||
#if 0
|
#if 0
|
||||||
fwprintf(stderr, L"Oops! test was given args:\n");
|
streams.err.append(L"Oops! test was given args:\n");
|
||||||
for (size_t i=0; i < argc; i++) {
|
for (size_t i=0; i < argc; i++) {
|
||||||
fwprintf(stderr, L"\t%ls\n", args.at(i).c_str());
|
streams.err.append_format(L"\t%ls\n", args.at(i).c_str());
|
||||||
}
|
}
|
||||||
fwprintf(stderr, L"and returned parse error: %ls\n", err.c_str());
|
streams.err.append_format(L"and returned parse error: %ls\n", err.c_str());
|
||||||
#endif
|
#endif
|
||||||
streams.err.append(err);
|
streams.err.append(err);
|
||||||
return BUILTIN_TEST_FAIL;
|
return BUILTIN_TEST_FAIL;
|
||||||
@@ -823,9 +823,9 @@ int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||||||
wcstring_list_t eval_errors;
|
wcstring_list_t eval_errors;
|
||||||
bool result = expr->evaluate(eval_errors);
|
bool result = expr->evaluate(eval_errors);
|
||||||
if (!eval_errors.empty() && !should_suppress_stderr_for_tests()) {
|
if (!eval_errors.empty() && !should_suppress_stderr_for_tests()) {
|
||||||
fwprintf(stderr, L"test returned eval errors:\n");
|
streams.err.append(L"test returned eval errors:\n");
|
||||||
for (size_t i = 0; i < eval_errors.size(); i++) {
|
for (size_t i = 0; i < eval_errors.size(); i++) {
|
||||||
fwprintf(stderr, L"\t%ls\n", eval_errors.at(i).c_str());
|
streams.err.append_format(L"\t%ls\n", eval_errors.at(i).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete expr;
|
delete expr;
|
||||||
|
|||||||
@@ -886,6 +886,7 @@ static bool get_mac_address(unsigned char macaddr[MAC_ADDRESS_MAX_LEN],
|
|||||||
#elif defined(HAVE_GETIFADDRS)
|
#elif defined(HAVE_GETIFADDRS)
|
||||||
|
|
||||||
// OS X and BSD
|
// OS X and BSD
|
||||||
|
#include <sys/socket.h>
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
static bool get_mac_address(unsigned char macaddr[MAC_ADDRESS_MAX_LEN],
|
static bool get_mac_address(unsigned char macaddr[MAC_ADDRESS_MAX_LEN],
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ static struct termios tty_modes_for_external_cmds;
|
|||||||
static void reader_super_highlight_me_plenty(int highlight_pos_adjust = 0, bool no_io = false);
|
static void reader_super_highlight_me_plenty(int highlight_pos_adjust = 0, bool no_io = false);
|
||||||
|
|
||||||
/// Variable to keep track of forced exits - see \c reader_exit_forced();
|
/// Variable to keep track of forced exits - see \c reader_exit_forced();
|
||||||
static int exit_forced;
|
static bool exit_forced;
|
||||||
|
|
||||||
/// Give up control of terminal.
|
/// Give up control of terminal.
|
||||||
static void term_donate() {
|
static void term_donate() {
|
||||||
@@ -360,7 +360,7 @@ static void term_steal() {
|
|||||||
common_handle_winch(0);
|
common_handle_winch(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int reader_exit_forced() { return exit_forced; }
|
bool reader_exit_forced() { return exit_forced; }
|
||||||
|
|
||||||
/// Given a command line and an autosuggestion, return the string that gets shown to the user.
|
/// Given a command line and an autosuggestion, return the string that gets shown to the user.
|
||||||
wcstring combine_command_and_autosuggestion(const wcstring &cmdline,
|
wcstring combine_command_and_autosuggestion(const wcstring &cmdline,
|
||||||
@@ -682,12 +682,16 @@ void reader_write_title(const wcstring &cmd, bool reset_cursor_position) {
|
|||||||
}
|
}
|
||||||
fputwc(L'\a', stdout);
|
fputwc(L'\a', stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
proc_pop_interactive();
|
proc_pop_interactive();
|
||||||
set_color(rgb_color_t::reset(), rgb_color_t::reset());
|
set_color(rgb_color_t::reset(), rgb_color_t::reset());
|
||||||
if (reset_cursor_position && !lst.empty()) {
|
if (reset_cursor_position && !lst.empty()) {
|
||||||
// Put the cursor back at the beginning of the line (issue #2453).
|
// Put the cursor back at the beginning of the line (issue #2453).
|
||||||
fputwc(L'\r', stdout);
|
fputwc(L'\r', stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: This should be removed when issue #3748 is fixed.
|
||||||
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reexecute the prompt command. The output is inserted into data->prompt_buff.
|
/// Reexecute the prompt command. The output is inserted into data->prompt_buff.
|
||||||
@@ -803,7 +807,7 @@ void restore_term_mode() {
|
|||||||
void reader_exit(int do_exit, int forced) {
|
void reader_exit(int do_exit, int forced) {
|
||||||
if (data) data->end_loop = do_exit;
|
if (data) data->end_loop = do_exit;
|
||||||
end_loop = do_exit;
|
end_loop = do_exit;
|
||||||
if (forced) exit_forced = 1;
|
if (forced) exit_forced = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reader_repaint_needed() {
|
void reader_repaint_needed() {
|
||||||
@@ -2204,6 +2208,8 @@ bool shell_is_exiting() {
|
|||||||
/// This function is called when the main loop notices that end_loop has been set while in
|
/// This function is called when the main loop notices that end_loop has been set while in
|
||||||
/// interactive mode. It checks if it is ok to exit.
|
/// interactive mode. It checks if it is ok to exit.
|
||||||
static void handle_end_loop() {
|
static void handle_end_loop() {
|
||||||
|
job_iterator_t jobs;
|
||||||
|
|
||||||
if (!reader_exit_forced()) {
|
if (!reader_exit_forced()) {
|
||||||
const parser_t &parser = parser_t::principal_parser();
|
const parser_t &parser = parser_t::principal_parser();
|
||||||
for (size_t i = 0; i < parser.block_count(); i++) {
|
for (size_t i = 0; i < parser.block_count(); i++) {
|
||||||
@@ -2213,23 +2219,22 @@ static void handle_end_loop() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool bg_jobs = false;
|
bool bg_jobs = false;
|
||||||
job_iterator_t jobs;
|
while (job_t *j = jobs.next()) {
|
||||||
while (job_t *j = jobs.next()) {
|
if (!job_is_completed(j)) {
|
||||||
if (!job_is_completed(j)) {
|
bg_jobs = true;
|
||||||
bg_jobs = true;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!data->prev_end_loop && bg_jobs) {
|
if (!data->prev_end_loop && bg_jobs) {
|
||||||
fputws(_(L"There are still jobs active (use the jobs command to see them).\n"), stdout);
|
fputws(_(L"There are still jobs active (use the jobs command to see them).\n"), stdout);
|
||||||
fputws(_(L"A second attempt to exit will terminate them.\n"), stdout);
|
fputws(_(L"A second attempt to exit will terminate them.\n"), stdout);
|
||||||
reader_exit(0, 0);
|
reader_exit(0, 0);
|
||||||
data->prev_end_loop = 1;
|
data->prev_end_loop = 1;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill remaining jobs before exiting.
|
// Kill remaining jobs before exiting.
|
||||||
@@ -2523,7 +2528,7 @@ const wchar_t *reader_readline(int nchars) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R_EOF: {
|
case R_EOF: {
|
||||||
exit_forced = 1;
|
exit_forced = true;
|
||||||
data->end_loop = 1;
|
data->end_loop = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ bool shell_is_exiting();
|
|||||||
void reader_handle_sigint();
|
void reader_handle_sigint();
|
||||||
|
|
||||||
/// This function returns true if fish is exiting by force, i.e. because stdin died.
|
/// This function returns true if fish is exiting by force, i.e. because stdin died.
|
||||||
int reader_exit_forced();
|
bool reader_exit_forced();
|
||||||
|
|
||||||
/// Test if the given shell command contains errors. Uses parser_test for testing. Suitable for
|
/// Test if the given shell command contains errors. Uses parser_test for testing. Suitable for
|
||||||
/// reader_set_test_function().
|
/// reader_set_test_function().
|
||||||
|
|||||||
37
tests/exit.expect
Normal file
37
tests/exit.expect
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# vim: set filetype=expect:
|
||||||
|
#
|
||||||
|
# Test handling of the `exit` command.
|
||||||
|
set pid [spawn $fish]
|
||||||
|
expect_prompt
|
||||||
|
|
||||||
|
# Verify that if we attempt to exit with a job in the background we get warned
|
||||||
|
# about that job and are told to type `exit` a second time.
|
||||||
|
send "sleep 111 &\r"
|
||||||
|
expect_prompt
|
||||||
|
send "exit\r"
|
||||||
|
expect "There are still jobs active"
|
||||||
|
expect "A second attempt to exit will terminate them."
|
||||||
|
expect_prompt
|
||||||
|
|
||||||
|
# Running anything other than `exit` should result in the same warning with
|
||||||
|
# the shell still running.
|
||||||
|
send "sleep 113 &\r"
|
||||||
|
expect_prompt
|
||||||
|
send "exit\r"
|
||||||
|
expect "There are still jobs active"
|
||||||
|
expect "A second attempt to exit will terminate them."
|
||||||
|
expect_prompt
|
||||||
|
|
||||||
|
# Verify that asking to exit a second time does so.
|
||||||
|
send "exit\r"
|
||||||
|
close
|
||||||
|
wait
|
||||||
|
|
||||||
|
# Verify all child processes have been killed. We don't use `-p $pid` because
|
||||||
|
# if the shell has a bug the child processes might have been reparented to pid
|
||||||
|
# 1 rather than killed.
|
||||||
|
set status [catch {exec pgrep -l -f "sleep 11"} output]
|
||||||
|
if {$status == 0} {
|
||||||
|
puts stderr "Commands spawned by the shell still running after `exit`"
|
||||||
|
puts stderr $output
|
||||||
|
}
|
||||||
0
tests/exit.expect.err
Normal file
0
tests/exit.expect.err
Normal file
0
tests/exit.expect.out
Normal file
0
tests/exit.expect.out
Normal file
28
tests/signals.expect
Normal file
28
tests/signals.expect
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# vim: set filetype=expect:
|
||||||
|
#
|
||||||
|
# Test signal handling for interactive shells.
|
||||||
|
|
||||||
|
# Verify that sending SIGHUP to the shell, such as will happen when the tty is
|
||||||
|
# closed by the terminal, terminates the shell and the foreground command and
|
||||||
|
# any background commands run from that shell.
|
||||||
|
set pid [spawn $fish]
|
||||||
|
expect_prompt
|
||||||
|
send "sleep 130 &\r"
|
||||||
|
expect_prompt
|
||||||
|
send "sleep 131 &\r"
|
||||||
|
expect_prompt
|
||||||
|
send "sleep 132\r"
|
||||||
|
exec -- kill -HUP $pid
|
||||||
|
|
||||||
|
# Verify the spawned fish shell has exited.
|
||||||
|
close
|
||||||
|
wait
|
||||||
|
|
||||||
|
# Verify all child processes have been killed. We don't use `-p $pid` because
|
||||||
|
# if the shell has a bug the child processes might have been reparented to pid
|
||||||
|
# 1 rather than killed.
|
||||||
|
set status [catch {exec pgrep -l -f "sleep 13"} output]
|
||||||
|
if {$status == 0} {
|
||||||
|
puts stderr "Commands spawned by the shell still running after SIGHUP"
|
||||||
|
puts stderr $output
|
||||||
|
}
|
||||||
0
tests/signals.expect.err
Normal file
0
tests/signals.expect.err
Normal file
0
tests/signals.expect.out
Normal file
0
tests/signals.expect.out
Normal file
Reference in New Issue
Block a user