Compare commits

..

40 Commits

Author SHA1 Message Date
ridiculousfish
e9da2f9c77 Correct the coverity scan incantation 2020-06-08 22:06:57 -07:00
ridiculousfish
62b69532b1 Attempt to fix coverity_scan build matrix in travis 2020-06-08 21:16:30 -07:00
ridiculousfish
2f1e8d9f8b Merge branch 'master' into coverity_scan_master 2020-06-08 00:27:50 -07:00
ridiculousfish
64c8cee001 Merge branch 'master' into coverity_scan_master 2020-02-08 16:29:41 -08:00
ridiculousfish
2ea6b8c128 Merge branch 'master' into coverity_scan_master 2019-03-05 21:46:40 -08:00
Aaron Gyes
ed844fa0ac Merge branch 'master' into coverity_scan_master
Synopsys reports that Coverity Scan is functioning again.
2019-02-14 12:43:05 -08:00
Aaron Gyes
b0bda695b5 coverity failed with 'Error details: :Failed to retrieve tar file'
which sounds like something broken on their end. Try again.
2018-12-16 00:21:08 -08:00
Aaron Gyes
e945a5f179 Merge branch 'master' into coverity_scan_master 2018-12-11 03:39:49 -08:00
ridiculousfish
dfeccf2a1e Merge branch 'master' into coverity_scan_master 2018-10-20 23:34:28 -07:00
ridiculousfish
593675e05e Merge branch 'master' into coverity_scan_master 2018-03-05 21:06:54 -08:00
Mahmoud Al-Qudsi
50a5460c17 Merge branch 'master' into coverity_scan_master 2018-02-14 19:25:48 -06:00
ridiculousfish
172436f508 Merge branch 'master' into coverity_scan_master 2018-02-08 22:27:18 -08:00
Mahmoud Al-Qudsi
10a3eedcab Merge branch 'master' into coverity_scan_master 2018-02-08 17:37:04 -06:00
Mahmoud Al-Qudsi
53d8d9e0d9 Merge branch 'master' into coverity_scan_master 2018-02-08 17:23:36 -06:00
Mahmoud Al-Qudsi
642edbc434 Drop SHOW_INTERACTIVE_LOG from targets 2018-02-08 16:35:02 -06:00
Mahmoud Al-Qudsi
d85bf9c0da Try building with clang++ instead
It seems that clang is the default build system on travis.
2018-02-08 15:30:08 -06:00
Mahmoud Al-Qudsi
37503f5f01 Correct arguments to cmake for coverity build_command_prepend 2018-02-08 15:20:38 -06:00
Mahmoud Al-Qudsi
193dbe2a78 Specify complete path to g++ for cmake via which 2018-02-08 15:15:41 -06:00
Mahmoud Al-Qudsi
e95b9c16f0 Remove hardcoded architecture 2018-02-08 11:43:27 -06:00
Mahmoud Al-Qudsi
d1bfea9ee5 Don't specify platform for libncurses 2018-02-08 11:40:22 -06:00
Mahmoud Al-Qudsi
c9c2cd069d Fix name of ninja-build package in travis apt config 2018-02-08 11:01:34 -06:00
Mahmoud Al-Qudsi
c5409335ee Define CMAKE_CXX_COMPILER 2018-02-08 10:58:51 -06:00
Mahmoud Al-Qudsi
db9259210d Fix travis build broken by coverity build instructions 2018-02-08 10:53:14 -06:00
Mahmoud Al-Qudsi
998b878dda Try to fix coverity_scan travis build
Merging in `master` broke the coverity_scan travis build. Trying to set
up the .travis.yml file to just trigger a coverity scan.
2018-02-08 10:48:17 -06:00
Mahmoud Al-Qudsi
32e2d36a7a Merge branch 'master' into coverity_scan_master 2018-02-08 10:34:13 -06:00
Aaron Gyes
37dc28f354 Merge branch 'master' into coverity_scan_master 2017-09-30 16:04:15 -07:00
ridiculousfish
20ee1ce94b Merge branch 'master' into coverity_scan_master 2017-02-01 10:39:56 -08:00
Aaron Gyes
5c95da56a4 Merge branch 'master' into coverity_scan_master 2016-11-07 18:49:52 -08:00
Aaron Gyes
82325778a5 Merge branch 'master' into coverity_scan_master 2016-10-17 14:48:51 -07:00
Aaron Gyes
49d8e71e1f Merge branch 'master' into coverity_scan_master 2016-10-17 14:15:28 -07:00
Aaron Gyes
a9d1fb23da Merge branch 'master' into coverity_scan_master 2016-10-07 15:54:05 -07:00
ridiculousfish
d8d194af63 Merge branch 'master' into coverity_scan_master 2016-07-31 02:25:01 -07:00
Aaron Gyes
85295488a6 Merge branch 'master' into coverity_scan_master 2016-07-24 00:16:45 -07:00
Aaron Gyes
7a8c5f53d5 Merge remote-tracking branch 'origin/master' into coverity_scan_master 2016-07-09 16:15:35 -07:00
Aaron Gyes
bec4c374f5 Coverity scan, not scanning.
See if restroing the exact same travis.yml this used to have fixes it.
2016-06-27 02:09:22 -07:00
Aaron Gyes
d925862350 Merge branch 'master' of https://github.com/fish-shell/fish-shell into coverity_scan_master 2016-06-27 02:04:37 -07:00
Aaron Gyes
1f2a2de414 Merge branch 'master' into coverity_scan_master 2016-06-26 16:51:08 -07:00
Aaron Gyes
c21d880f34 Merge branch 'master' into coverity_scan_master 2016-06-10 06:26:12 -07:00
ridiculousfish
e1dde5d7e1 Merge branch 'master' into coverity_scan_master 2016-03-03 18:52:28 -08:00
ridiculousfish
66d7850b18 Squashed attempt at adding Coverity Scan support to TravisCI 2016-03-03 18:13:21 -08:00
1334 changed files with 184494 additions and 114679 deletions

View File

@@ -4,13 +4,12 @@ packages:
- ninja - ninja
- ncurses-dev - ncurses-dev
- pcre2-dev - pcre2-dev
- python3 - expect
- py-pip - python
sources: sources:
- https://git.sr.ht/~faho/fish - https://git.sr.ht/~faho/fish
tasks: tasks:
- build: | - build: |
pip3 install pexpect
cd fish cd fish
mkdir build || : mkdir build || :
cd build cd build

View File

@@ -2,8 +2,8 @@ image: archlinux
packages: packages:
- cmake - cmake
- ninja - ninja
- expect
- python - python
- python-pexpect
sources: sources:
- https://git.sr.ht/~faho/fish - https://git.sr.ht/~faho/fish
tasks: tasks:

View File

@@ -3,11 +3,11 @@ packages:
- ncurses - ncurses
- gcc - gcc
- gettext - gettext
- expect
- cmake - cmake
- gmake - gmake
- pcre2 - pcre2
- python - python
- py38-pexpect
sources: sources:
- https://git.sr.ht/~faho/fish - https://git.sr.ht/~faho/fish
tasks: tasks:

View File

@@ -1,5 +1,5 @@
--- ---
Checks: 'clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-valist.Uninitialized,cert-*,performance-*,portability-*,-modernize-use-auto,modernize-loop-convert,modernize-use-bool-literals,modernize-use-using,hicpp-uppercase-literal-suffix,readability-make-member-function-const,readability-redundant-string-init,readability-inconsistent-declaration-parameter-name,readability-redundant-access-specifiers,-performance-noexcept-move-constructor,-cert-dcl21-cpp,-cert-dcl37-c,-cert-dcl50-cpp,-cert-dcl51-cpp,-cert-str34-c,-cert-env33-c,misc-static-assert,readability-use-anyofallof,readability-simplify-*,readability-redundant-*,modernize-redundant-void-arg,modernize-make-shared,modernize-make-unique,modernize-loop-convert,' Checks: 'clang-diagnostic-*,clang-analyzer-*,cert-*,performance-*,portability-*,modernize-use-auto,modernize-loop-convert,modernize-use-bool-literals,modernize-use-using,hicpp-uppercase-literal-suffix,readability-make-member-function-const,readability-redundant-string-init,readability-inconsistent-declaration-parameter-name,readability-redundant-access-specifiers'
WarningsAsErrors: '' WarningsAsErrors: ''
HeaderFilterRegex: '' HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false AnalyzeTemporaryDtors: false

View File

@@ -10,6 +10,3 @@ varFuncNullUB
unmatchedSuppression unmatchedSuppression
// Suppress this one because it reports assert(condition && "message"), which we use all over the place // Suppress this one because it reports assert(condition && "message"), which we use all over the place
incorrectStringBooleanError incorrectStringBooleanError
// This is of very little use and pops up *everywhere*.
useStlAlgorithm

View File

@@ -20,9 +20,3 @@ indent_size = 2
[Dockerfile] [Dockerfile]
indent_size = 2 indent_size = 2
[share/{completions,functions}/**.fish]
max_line_length = none
[COMMIT_EDITMSG]
max_line_length = 80

10
.gitattributes vendored
View File

@@ -21,13 +21,11 @@
/.github/* export-ignore /.github/* export-ignore
/.builds export-ignore /.builds export-ignore
/.builds/* export-ignore /.builds/* export-ignore
/.travis.yml export-ignore
# for linguist; let github identify our project as C++ instead of C due to pcre2 # for linguist; let github identify our project as C++ instead of C due to pcre2
pcre2/** linguist-vendored /pcre2/* linguist-vendored
angular.js linguist-vendored angular.js linguist-vendored
angular-*.js linguist-vendored /doc_src/* linguist-documentation
doc_src/** linguist-documentation
*.fish linguist-language=fish *.fish linguist-language=fish
src/*.h linguist-language=c++ /tests/*.in linguist-language=fish
src/builtins/*.h linguist-language=c++
share/completions/*.fish linguist-documentation

View File

@@ -12,5 +12,3 @@ Please tell us if you tried fish without third-party customizations by executing
Tell us how to reproduce the problem. Including an asciinema.org recording is useful for problems that involve the visual display of fish output such as its prompt. Tell us how to reproduce the problem. Including an asciinema.org recording is useful for problems that involve the visual display of fish output such as its prompt.
--> -->
**YOUR TEXT HERE**

View File

@@ -1,43 +0,0 @@
name: "CodeQL"
on:
push:
branches: [ master ]
schedule:
- cron: '18 22 * * 2'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: true
matrix:
language: [ 'cpp', 'javascript', 'python' ]
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View File

@@ -2,11 +2,8 @@ name: 'Lock threads'
on: on:
schedule: schedule:
- cron: '0 18 * * 1' - cron: '0 * * * *'
# │ │ │ │ │
# min 0-59 ┘ │ │ │ └ weekday 0-6
# hour 0-23 ┘ │ └ month 1-12
# └ day 1-31
jobs: jobs:
lock: lock:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -14,6 +11,6 @@ jobs:
- uses: dessant/lock-threads@v2 - uses: dessant/lock-threads@v2
with: with:
github-token: ${{ github.token }} github-token: ${{ github.token }}
issue-lock-inactive-days: '365' issue-lock-inactive-days: '90'
pr-lock-inactive-days: '365' pr-lock-inactive-days: '90'
issue-exclude-labels: 'question, needs more info' issue-exclude-labels: 'question'

View File

@@ -1,10 +1,10 @@
name: make test name: C/C++ CI
on: [push, pull_request] on:
push:
env: branches: [ master ]
CTEST_PARALLEL_LEVEL: "1" pull_request:
CMAKE_BUILD_PARALLEL_LEVEL: "4" branches: [ master ]
jobs: jobs:
ubuntu: ubuntu:
@@ -15,14 +15,8 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Install deps - name: Install deps
run: | run: |
sudo apt install gettext libncurses5-dev libpcre2-dev python3-pip tmux sudo apt install expect gettext libncurses5-dev libpcre2-dev
sudo pip3 install pexpect
# Generate a locale that uses a comma as decimal separator.
sudo locale-gen fr_FR.UTF-8
- name: cmake - name: cmake
env:
# Some warnings upgraded to errors to match Open Build Service platforms
CXXFLAGS: "-Werror=address -Werror=return-type"
run: | run: |
mkdir build && cd build mkdir build && cd build
cmake .. cmake ..
@@ -33,100 +27,22 @@ jobs:
run: | run: |
make test make test
ubuntu-32bit-vendored-pcre2: # macos:
runs-on: ubuntu-latest # runs-on: macos-latest
steps: # steps:
- uses: actions/checkout@v2 # - uses: actions/checkout@v2
- name: Install deps # - name: Install deps
run: | # run: |
sudo apt update # brew install pcre2
sudo apt install gettext lib32ncurses5-dev python3-pip g++-multilib tmux # - name: cmake
sudo pip3 install pexpect # run: |
- name: cmake # mkdir build && cd build
env: # cmake ..
CXXFLAGS: "-m32 -Werror=address -Werror=return-type" # - name: make
CFLAGS: "-m32" # run: |
run: | # make
mkdir build && cd build # - name: make test
cmake -DFISH_USE_SYSTEM_PCRE2=OFF .. # run: |
- name: make # make test
run: |
make
- name: make test
run: |
make test
ubuntu-asan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install deps
run: |
sudo apt install gettext libncurses5-dev libpcre2-dev python3-pip tmux
sudo pip3 install pexpect
- name: cmake
env:
CC: clang
CXX: clang++
CXXFLAGS: "-fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address"
ASAN_OPTIONS: check_initialization_order=1:detect_stack_use_after_return=1:detect_leaks=1
UBSAN_OPTIONS: print_stacktrace=1:report_error_type=1
run: |
mkdir build && cd build
cmake ..
- name: make
run: |
make
- name: make test
run: |
make test
ubuntu-threadsan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install deps
run: |
sudo apt install gettext libncurses5-dev libpcre2-dev python3-pip tmux
sudo pip3 install pexpect
- name: cmake
env:
CC: clang
CXX: clang++
CXXFLAGS: "-fsanitize=thread"
run: |
mkdir build && cd build
cmake ..
- name: make
run: |
make
- name: make test
run: |
make test
macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Install deps
run: |
sudo pip3 install pexpect
brew install tmux
- name: cmake
run: |
mkdir build && cd build
cmake -DWITH_GETTEXT=NO ..
- name: make
run: |
make
- name: make test
run: |
make test

122
.travis.yml Normal file
View File

@@ -0,0 +1,122 @@
language: cpp
dist: xenial
sudo: required
matrix:
include:
- os: linux
compiler: gcc
addons:
apt:
packages:
- expect
- gettext
- libncurses5-dev
- libpcre2-dev
- python3
- python3-pip
before_install:
- sudo pip3 install pexpect
env:
# Some warnings upgraded to errors to match Open Build Service platforms
- CXXFLAGS="-Werror=address -Werror=return-type"
- os: linux
compiler: gcc
addons:
apt:
packages: # Don't use libpcre2-dev here, so that one build uses the vendored code
- expect
- gettext
- lib32ncurses5-dev
- g++-multilib
- python3
- python3-pip
before_install:
- sudo pip3 install pexpect
env:
- CXXFLAGS="-m32 -Werror=address -Werror=return-type" CFLAGS="-m32"
- os: linux
compiler: clang
env:
- CXXFLAGS="-fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address"
- ASAN_OPTIONS=check_initialization_order=1:detect_stack_use_after_return=1:detect_leaks=1
- UBSAN_OPTIONS=print_stacktrace=1:report_error_type=1:suppressions=$TRAVIS_BUILD_DIR/build_tools/ubsan.blacklist
before_install:
- sudo pip3 install pexpect
addons:
apt:
packages:
- expect
- gettext
- libncurses5-dev
- libpcre2-dev
- python
- python3
- python3-pip
- os: linux
compiler: clang
env:
- CXXFLAGS="-fsanitize=thread"
before_install:
- sudo pip3 install pexpect
addons:
apt:
packages:
- expect
- gettext
- libncurses5-dev
- libpcre2-dev
- python3
- python3-pip
- os: linux
compiler: gcc
addons:
coverity_scan:
project:
name: "fish-shell/fish-shell"
description: "The friendly interactive shell"
notification_email: corydoras@ridiculousfish.com
build_command_prepend: "mkdir -p build; cd build; cmake -G Ninja .."
build_command: "ninja"
branch_pattern: coverity_scan_master
apt:
packages:
- expect
- gettext
- libncurses5-dev
- libpcre2-dev
- python3
- python3-pip
before_install:
- sudo pip3 install pexpect
- echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
env:
- secure: "Q1AS5iEi17s+xsRaMwfkxmm62UDaV47uE39pvXsNL+DO9YWbMMuhTpIOeYhxLvFNL3LMUFU2TwVpVRYX2YFGhNNaMSmjQfyQ+7q7/oSEo0aSqvQkwelpK/pwuRAXdv1MU4aQ6FrCEQ4VMO45WRo0o5WD26pvxjqRyAQ6ry+serA="
# Some warnings upgraded to errors to match Open Build Service platforms
- CXXFLAGS="-Werror=address -Werror=return-type"
- os: osx
before_install:
- sudo pip3 install pexpect
fast_finish: true
script:
- cmake -DCMAKE_INSTALL_PREFIX=$HOME/prefix . || cat CMakeFiles/CMakeError.log &&
make -j2 &&
make install &&
make test SHOW_INTERACTIVE_LOG=1
notifications:
# Some items are encrypted so that notifications from other repositories
# don't flood the official repositories.
irc:
channels:
#- "irc.oftc.net#fish"
secure: "eRk9KGZ5+mrlD2SoI8yg2Sp8OYrh7YPyGe3WCDQUwTnNgNDII34rbM9a6UOA/l7AeWSNY8joLq5xVLCU4wpFgUcJ11SYIpMnLosZK29OW4ubDOHmdBDvJ971rLgAVG9cXngZtIxEVVxN/jnS1Qr8GKZx4DjkaTMgz1pemb4WxCc="
template:
- "%{repository}#%{build_number} (%{commit} on %{branch} by %{author}): %{message} Details at %{build_url}"
use_notice: true
skip_join: true
webhooks:
urls:
#- https://webhooks.gitter.im/e/61821cec3015bf0f8bb1
secure: fPfOmxnC3MCsfR1oocVFeWLawGcRZkn+8fNHlSOeZ+SqqoZfcCHgQTvQ22TqmVl1yvkXbNlaXjo6dbVzTOAh7r7H0bRMEKBVh3dQS7wqjB1sKivpXd8PAS3BTj5MQpGeJzdHnDuwVlwDktGtfHfhGeq1Go/4IosOq8u+6RTe28g=

View File

@@ -20,22 +20,20 @@ _GENERATOR!=which ninja 2>/dev/null >/dev/null && echo Ninja || echo "Unix Makef
GENERATOR?=$(_GENERATOR) GENERATOR?=$(_GENERATOR)
.if $(GENERATOR) == "Ninja" .if $(GENERATOR) == "Ninja"
BUILDFILE=build.ninja BUILDFILE=build/build.ninja
.else .else
BUILDFILE=Makefile BUILDFILE=build/Makefile
.endif .endif
PREFIX?=/usr/local PREFIX?=/usr/local
.PHONY: build/fish
build/fish: build/$(BUILDFILE) build/fish: build/$(BUILDFILE)
$(CMAKE) --build build $(CMAKE) --build build
# Don't split the mkdir into its own rule because that would cause CMake to regenerate the build build:
# files after each build (because it adds the mdate of the build directory into the out-of-date
# calculation tree). GNUmake supports order-only dependencies, BSDmake does not seem to.
build/$(BUILDFILE):
mkdir -p build mkdir -p build
build/$(BUILDFILE): build
cd build; $(CMAKE) .. -G "$(GENERATOR)" -DCMAKE_INSTALL_PREFIX="$(PREFIX)" -DCMAKE_EXPORT_COMPILE_COMMANDS=1 cd build; $(CMAKE) .. -G "$(GENERATOR)" -DCMAKE_INSTALL_PREFIX="$(PREFIX)" -DCMAKE_EXPORT_COMPILE_COMMANDS=1
.PHONY: install .PHONY: install

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.2)
if(POLICY CMP0066) if(POLICY CMP0066)
cmake_policy(SET CMP0066 OLD) cmake_policy(SET CMP0066 OLD)
@@ -16,50 +16,62 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
set(DEFAULT_BUILD_TYPE "RelWithDebInfo") set(DEFAULT_BUILD_TYPE "RelWithDebInfo")
# Generate Xcode schemas (but not for tests). # Use the default flags (#6296) but remove -DNDEBUG so that asserts remain enabled.
set(CMAKE_XCODE_GENERATE_SCHEME 1) string(REPLACE "-DNDEBUG" ""
CMAKE_CXX_FLAGS_RELWITHDEBINFO
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
string(REPLACE "-DNDEBUG" ""
CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE}")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to default '${DEFAULT_BUILD_TYPE}'") message(STATUS "Setting build type to default '${DEFAULT_BUILD_TYPE}'")
set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}") set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}")
endif() endif()
# Error out when linking statically, it doesn't work.
if (CMAKE_EXE_LINKER_FLAGS MATCHES ".*-static.*")
message(FATAL_ERROR "Fish does not support static linking")
endif()
# Force colored warnings in Ninja's output, if the compiler has -fdiagnostics-color support. # Force colored warnings in Ninja's output, if the compiler has -fdiagnostics-color support.
# Rationale in https://github.com/ninja-build/ninja/issues/814 # Rationale in https://github.com/ninja-build/ninja/issues/814
if (CMAKE_GENERATOR STREQUAL "Ninja" AND if (CMAKE_GENERATOR STREQUAL "Ninja" AND
((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) OR ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) OR
(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5) OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5) OR
(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0))) (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)))
add_compile_options(-fdiagnostics-color=always) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color=always")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
endif() endif()
# Enable a whole bunch of warnings, but turn off: # Enable a whole bunch of warnings, but turn off:
# - implicit fallthrough because that does not recognize some cases where it's desired (and I *really* want this one!)
# - comment because we use a bunch of those, and they're not really all that harmful. # - comment because we use a bunch of those, and they're not really all that harmful.
# - address, because that occurs for our mkostemp check (weak-linking requires us to compare `&mkostemp == nullptr`). # - address, because that occurs for our mkostemp check (weak-linking requires us to compare `&mkostemp == nullptr`).
add_compile_options(-Wall -Wextra -Wno-comment -Wno-address) # - strict-aliasing, because on old GCCs (*Travis*) those are triggered by maybe.h, so you get it every time it is included.
# - redundant-move, because we have one that is required on old libc
if ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra \
add_compile_options(-Wunused-template -Wunused-local-typedef -Wunused-macros) -Wno-implicit-fallthrough \
endif() -Wno-comment \
-Wno-address \
-Wno-strict-aliasing \
-Wno-redundant-move \
")
# Disable exception handling. # Disable exception handling.
add_compile_options(-fno-exceptions) add_compile_options(-fno-exceptions)
# Undefine NDEBUG to keep assert() in release builds. # Prefer the gold linker because it doesn't emit useless warnings about sys_nerr and _sys_errlist.
add_definitions(-UNDEBUG) if (UNIX AND NOT APPLE)
execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
if ("${LD_VERSION}" MATCHES "GNU gold")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
endif()
endif()
# Hide the CMake Rules directories in Xcode projects. # Hide the CMake Rules directories in Xcode projects.
source_group("CMake Rules" REGULAR_EXPRESSION "^$") source_group("CMake Rules" REGULAR_EXPRESSION "^$")
# Put source and header files at top level under targets. # Put source and header files at top level under targets.
source_group("Source Files" REGULAR_EXPRESSION ".*\\.cpp") source_group("Source Files" REGULAR_EXPRESSION "^$")
source_group("Header Files" REGULAR_EXPRESSION ".*\\.h") source_group("Header Files" REGULAR_EXPRESSION "^$")
source_group("Builtins" "builtins/") source_group("Builtins" REGULAR_EXPRESSION "builtin_.*")
# Support folders. # Support folders.
set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(GLOBAL PROPERTY USE_FOLDERS ON)
@@ -83,38 +95,33 @@ if(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
endif() endif()
# List of sources for builtin functions. # All objects that the system needs to build fish, except fish.cpp
set(FISH_BUILTIN_SRCS
src/builtin.cpp src/builtins/argparse.cpp
src/builtins/bg.cpp src/builtins/bind.cpp src/builtins/block.cpp
src/builtins/builtin.cpp src/builtins/cd.cpp src/builtins/command.cpp
src/builtins/commandline.cpp src/builtins/complete.cpp src/builtins/contains.cpp
src/builtins/disown.cpp src/builtins/echo.cpp src/builtins/emit.cpp
src/builtins/eval.cpp src/builtins/exit.cpp src/builtins/fg.cpp
src/builtins/function.cpp src/builtins/functions.cpp src/builtins/history.cpp
src/builtins/jobs.cpp src/builtins/math.cpp src/builtins/printf.cpp
src/builtins/pwd.cpp src/builtins/random.cpp src/builtins/read.cpp
src/builtins/realpath.cpp src/builtins/return.cpp src/builtins/set.cpp
src/builtins/set_color.cpp src/builtins/source.cpp src/builtins/status.cpp
src/builtins/string.cpp src/builtins/test.cpp src/builtins/type.cpp src/builtins/ulimit.cpp
src/builtins/wait.cpp)
# List of other sources.
set(FISH_SRCS set(FISH_SRCS
src/ast.cpp src/autoload.cpp src/color.cpp src/common.cpp src/complete.cpp src/env.cpp src/autoload.cpp src/builtin.cpp src/builtin_bg.cpp src/builtin_bind.cpp
src/env_dispatch.cpp src/env_universal_common.cpp src/event.cpp src/exec.cpp src/builtin_block.cpp src/builtin_builtin.cpp src/builtin_cd.cpp
src/expand.cpp src/fallback.cpp src/fd_monitor.cpp src/fish_version.cpp src/builtin_command.cpp src/builtin_commandline.cpp
src/flog.cpp src/function.cpp src/future_feature_flags.cpp src/highlight.cpp src/builtin_complete.cpp src/builtin_contains.cpp src/builtin_disown.cpp
src/history.cpp src/history_file.cpp src/input.cpp src/input_common.cpp src/builtin_echo.cpp src/builtin_emit.cpp src/builtin_exit.cpp
src/intern.cpp src/io.cpp src/iothread.cpp src/job_group.cpp src/kill.cpp src/builtin_fg.cpp src/builtin_function.cpp src/builtin_functions.cpp
src/null_terminated_array.cpp src/operation_context.cpp src/output.cpp src/builtin_argparse.cpp src/builtin_history.cpp src/builtin_jobs.cpp
src/pager.cpp src/parse_execution.cpp src/parse_tree.cpp src/parse_util.cpp src/builtin_math.cpp src/builtin_printf.cpp src/builtin_pwd.cpp
src/parser.cpp src/parser_keywords.cpp src/path.cpp src/postfork.cpp src/builtin_random.cpp src/builtin_read.cpp src/builtin_realpath.cpp
src/proc.cpp src/reader.cpp src/redirection.cpp src/screen.cpp src/builtin_return.cpp src/builtin_set.cpp src/builtin_set_color.cpp
src/signal.cpp src/termsize.cpp src/timer.cpp src/tinyexpr.cpp src/builtin_source.cpp src/builtin_status.cpp src/builtin_string.cpp
src/tokenizer.cpp src/topic_monitor.cpp src/trace.cpp src/utf8.cpp src/util.cpp src/builtin_test.cpp src/builtin_ulimit.cpp src/builtin_wait.cpp src/builtin_eval.cpp
src/wait_handle.cpp src/wcstringutil.cpp src/wgetopt.cpp src/wildcard.cpp src/color.cpp src/common.cpp src/complete.cpp src/env.cpp src/env_dispatch.cpp
src/wutil.cpp src/fds.cpp src/env_universal_common.cpp src/event.cpp src/exec.cpp src/expand.cpp
src/fallback.cpp src/fish_version.cpp src/function.cpp src/highlight.cpp
src/history.cpp src/history_file.cpp src/input.cpp src/input_common.cpp src/intern.cpp
src/io.cpp src/iothread.cpp src/kill.cpp src/output.cpp src/pager.cpp
src/parse_execution.cpp src/parse_productions.cpp src/parse_tree.cpp
src/parse_util.cpp src/parser.cpp src/parser_keywords.cpp src/path.cpp
src/postfork.cpp src/proc.cpp src/reader.cpp src/sanity.cpp src/screen.cpp
src/signal.cpp src/tinyexpr.cpp src/tnode.cpp src/tokenizer.cpp src/utf8.cpp src/util.cpp
src/wcstringutil.cpp src/wgetopt.cpp src/wildcard.cpp src/wutil.cpp
src/future_feature_flags.cpp src/redirection.cpp src/topic_monitor.cpp
src/flog.cpp src/trace.cpp src/timer.cpp src/null_terminated_array.cpp
src/operation_context.cpp src/fd_monitor.cpp src/termsize.cpp
) )
# Header files are just globbed. # Header files are just globbed.
@@ -166,13 +173,11 @@ function(FISH_LINK_DEPS_AND_SIGN target)
endfunction(FISH_LINK_DEPS_AND_SIGN) endfunction(FISH_LINK_DEPS_AND_SIGN)
# Define libfish.a. # Define libfish.a.
add_library(fishlib STATIC ${FISH_SRCS} ${FISH_BUILTIN_SRCS}) add_library(fishlib STATIC ${FISH_SRCS})
target_sources(fishlib PRIVATE ${FISH_HEADERS}) target_sources(fishlib PRIVATE ${FISH_HEADERS})
target_link_libraries(fishlib target_link_libraries(fishlib
${CURSES_LIBRARY} ${CURSES_EXTRA_LIBRARY} Threads::Threads ${CMAKE_DL_LIBS} ${CURSES_LIBRARY} ${CURSES_EXTRA_LIBRARY} Threads::Threads ${CMAKE_DL_LIBS}
${PCRE2_LIB} ${Intl_LIBRARIES} ${ATOMIC_LIBRARY}) ${PCRE2_LIB} ${Intl_LIBRARIES} ${ATOMIC_LIBRARY})
target_include_directories(fishlib PRIVATE
${CURSES_INCLUDE_DIRS})
# Define fish. # Define fish.
add_executable(fish src/fish.cpp) add_executable(fish src/fish.cpp)
@@ -206,15 +211,6 @@ include(cmake/Install.cmake)
# Mac app. # Mac app.
include(cmake/MacApp.cmake) include(cmake/MacApp.cmake)
# ThreadSanitizer likes to muck with signal handlers, which interferes
# with fish_test_helper printing the ignored signal mask.
# Ensure fish_test_helper does not use TSan.
# Note the environment var is CXXFLAGS, but the CMake var is CMAKE_CXX_FLAGS.
if (CMAKE_CXX_FLAGS MATCHES ".*-fsanitize=thread.*")
target_compile_options(fish_test_helper PRIVATE "-fno-sanitize=all")
target_link_libraries(fish_test_helper "-fno-sanitize=all")
endif()
# Lint targets # Lint targets
# This could be implemented as target properties, but the script has the useful feature of only # This could be implemented as target properties, but the script has the useful feature of only
# checking the currently-staged commands # checking the currently-staged commands

View File

@@ -1,129 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@@ -3,29 +3,63 @@ Guidelines For Developers
This document provides guidelines for making changes to the fish-shell This document provides guidelines for making changes to the fish-shell
project. This includes rules for how to format the code, naming project. This includes rules for how to format the code, naming
conventions, et cetera. conventions, et cetera. Generally known as the style of the code. It
also includes recommended best practices such as creating a Travis CI
account so you can verify that your changes pass all the tests before
making a pull request.
In short: See the bottom of this document for help on installing the linting and
style reformatting tools discussed in the following sections.
- Be conservative in what you need (``C++11``, few dependencies) Fish source should limit the C++ features it uses to those available in
- Use automated tools to help you (including ``make test``, ``build_tools/style.fish`` and ``make lint``) C++11. It should not use exceptions.
General Before introducing a new dependency, please make it optional with
------- graceful failure if possible. Add any new dependencies to the README.rst
under the *Running* and/or *Building* sections.
Fish uses C++11. Newer C++ features should not be used to make it possible to use on older systems. Versioning
----------
It does not use exceptions, they are disabled at build time with ``-fno-exceptions``. The fish version is constructed by the *build_tools/git_version_gen.sh*
script. For developers the version is the branch name plus the output of
``git describe --always --dirty``. Normally the main part of the version
will be the closest annotated tag. Which itself is usually the most
recent release number (e.g., ``2.6.0``).
Don't introduce new dependencies unless absolutely necessary, and if you do, Include What You Use
please make it optional with graceful failure if possible. --------------------
Add any new dependencies to the README.rst under the *Running* and/or *Building* sections.
This also goes for completion scripts and functions - if at all possible, they should only use You should not depend on symbols being visible to a ``*.cpp`` module
POSIX-compatible invocations of any tools, and no superfluous dependencies. from ``#include`` statements inside another header file. In other words
if your module does ``#include "common.h"`` and that header does
``#include "signal.h"`` your module should not assume the sub-include is
present. It should instead directly ``#include "signal.h"`` if it needs
any symbol from that header. That makes the actual dependencies much
clearer. It also makes it easy to modify the headers included by a
specific header file without having to worry that will break any module
(or header) that includes a particular header.
E.g. some completions deal with JSON data. In those it's preferable to use python to handle it, To help enforce this rule the ``make lint`` (and ``make lint-all``)
as opposed to ``jq``, because fish already optionally uses python elsewhere. (It also happens to be quite a bit *faster*) command will run the
`include-what-you-use <https://include-what-you-use.org/>`__ tool. You
can find the IWYU project on
`github <https://github.com/include-what-you-use/include-what-you-use>`__.
To install the tool on OS X youll need to add a
`formula <https://github.com/jasonmp85/homebrew-iwyu>`__ then install
it:
::
brew tap jasonmp85/iwyu
brew install iwyu
On Ubuntu you can install it via ``apt-get``:
::
sudo apt-get install iwyu
Lint Free Code Lint Free Code
-------------- --------------
@@ -35,6 +69,10 @@ potential bugs or code that is extremely hard to understand. They also
help ensure the code has a consistent style and that it avoids patterns help ensure the code has a consistent style and that it avoids patterns
that tend to confuse people. that tend to confuse people.
Ultimately we want lint free code. However, at the moment a lot of
cleanup is required to reach that goal. For now simply try to avoid
introducing new lint.
To make linting the code easy there are two make targets: ``lint`` and To make linting the code easy there are two make targets: ``lint`` and
``lint-all``. The latter does exactly what the name implies. The former ``lint-all``. The latter does exactly what the name implies. The former
will lint any modified but not committed ``*.cpp`` files. If there is no will lint any modified but not committed ``*.cpp`` files. If there is no
@@ -45,6 +83,8 @@ help catch mistakes such as using ``wcwidth()`` rather than
``fish_wcwidth()``. Please add a new rule if you find similar mistakes ``fish_wcwidth()``. Please add a new rule if you find similar mistakes
being made. being made.
Fish also depends on ``diff`` and ``expect`` for its tests.
Dealing With Lint Warnings Dealing With Lint Warnings
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -111,10 +151,10 @@ changes.
Configuring Your Editor for Fish C++ Code Configuring Your Editor for Fish C++ Code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Vim ViM
^^^ ^^^
As of Vim 7.4 it does not recognize triple-slash comments as used by As of ViM 7.4 it does not recognize triple-slash comments as used by
Doxygen and the OS X Xcode IDE to flag comments that explain the Doxygen and the OS X Xcode IDE to flag comments that explain the
following C symbol. This means the ``gq`` key binding to reformat such following C symbol. This means the ``gq`` key binding to reformat such
comments doesnt behave as expected. You can fix that by adding the comments doesnt behave as expected. You can fix that by adding the
@@ -124,10 +164,15 @@ following to your vimrc:
autocmd Filetype c,cpp setlocal comments^=:/// autocmd Filetype c,cpp setlocal comments^=:///
If you use Vim I recommend the `vim-clang-format If you use ViM I recommend the `vim-clang-format
plugin <https://github.com/rhysd/vim-clang-format>`__ by plugin <https://github.com/rhysd/vim-clang-format>`__ by
[@rhysd](https://github.com/rhysd). [@rhysd](https://github.com/rhysd).
You can also get ViM to provide reasonably correct behavior by
installing
http://www.vim.org/scripts/script.php?script_id=2636
Emacs Emacs
^^^^^ ^^^^^
@@ -136,7 +181,7 @@ If you use Emacs: TBD
Configuring Your Editor for Fish Scripts Configuring Your Editor for Fish Scripts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you use Vim: Install `vim-fish <https://github.com/dag/vim-fish>`__, If you use ViM: Install `vim-fish <https://github.com/dag/vim-fish>`__,
make sure you have syntax and filetype functionality in ``~/.vimrc``: make sure you have syntax and filetype functionality in ``~/.vimrc``:
:: ::
@@ -172,8 +217,8 @@ made to run fish_indent via e.g.
Suppressing Reformatting of C++ Code Suppressing Reformatting of C++ Code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can tell ``clang-format`` to not reformat a block by enclosing it in If you have a good reason for doing so you can tell ``clang-format`` to
comments like this: not reformat a block of code by enclosing it in comments like this:
:: ::
@@ -181,6 +226,10 @@ comments like this:
code to ignore code to ignore
// clang-format on // clang-format on
However, as I write this there are no places in the code where we use
this and I cant think of any legitimate reasons for exempting blocks of
code from clang-format.
Fish Script Style Guide Fish Script Style Guide
----------------------- -----------------------
@@ -242,27 +291,16 @@ Testing
------- -------
The source code for fish includes a large collection of tests. If you The source code for fish includes a large collection of tests. If you
are making any changes to fish, running these tests is a good way to make are making any changes to fish, running these tests is mandatory to make
sure the behaviour remains consistent and regressions are not sure the behaviour remains consistent and regressions are not
introduced. Even if you dont run the tests on your machine, they will introduced. Even if you dont run the tests on your machine, they will
still be run via Github Actions. still be run via the `Travis
CI <https://travis-ci.org/fish-shell/fish-shell>`__ service.
You are strongly encouraged to add tests when changing the functionality You are strongly encouraged to add tests when changing the functionality
of fish, especially if you are fixing a bug to help ensure there are no of fish, especially if you are fixing a bug to help ensure there are no
regressions in the future (i.e., we dont reintroduce the bug). regressions in the future (i.e., we dont reintroduce the bug).
The tests can be found in three places:
- src/fish_tests.cpp for tests to the core C++ code
- tests/checks for script tests, run by `littlecheck <https://github.com/ridiculousfish/littlecheck>`__
- tests/pexpects for interactive tests using `pexpect <https://pexpect.readthedocs.io/en/stable/>`__
When in doubt, the bulk of the tests should be added as a littlecheck test in tests/checks, as they are the easiest to modify and run, and much faster and more dependable than pexpect tests. The syntax is fairly self-explanatory. It's a fish script with the expected output in ``# CHECK:`` or ``# CHECKERR:`` (for stderr) comments.
fish_tests.cpp is mostly useful for unit tests - if you wish to test that a function does the correct thing for given input, use it.
The pexpects are written in python and can simulate input and output to/from a terminal, so they are needed for anything that needs actual interactivity. The runner is in build_tools/pexpect_helper.py, in case you need to modify something there.
Local testing Local testing
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
@@ -273,6 +311,32 @@ The tests can be run on your local computer on all operating systems.
cmake path/to/fish-shell cmake path/to/fish-shell
make test make test
Travis CI Build and Test
~~~~~~~~~~~~~~~~~~~~~~~~
The Travis Continuous Integration services can be used to test your
changes using multiple configurations. This is the same service that the
fish-shell project uses to ensure new changes havent broken anything.
Thus it is a really good idea that you leverage Travis CI before making
a pull request to avoid potential embarrassment at breaking the build.
You will need to `fork the fish-shell repository on
GitHub <https://help.github.com/articles/fork-a-repo/>`__, then setup
Travis to test your changes before making a pull request.
1. `Sign in to Travis CI <https://travis-ci.org/auth>`__ with your
GitHub account, accepting the GitHub access permissions confirmation.
2. Once youre signed in and your repositories are synchronized, go to
your `profile page <https://travis-ci.org/profile>`__ and enable the
fish-shell repository.
3. Push your changes to GitHub.
Youll receive an email when the tests are complete telling you whether
or not any tests failed.
Youll find the configuration used to control Travis in the
``.travis.yml`` file.
Git hooks Git hooks
~~~~~~~~~ ~~~~~~~~~
@@ -349,7 +413,7 @@ To install the lint checkers on Debian-based Linux distributions:
sudo apt-get install oclint sudo apt-get install oclint
sudo apt-get install cppcheck sudo apt-get install cppcheck
Installing the Formatting Tools Installing the Reformatting Tools
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mac OS X: Mac OS X:
@@ -362,7 +426,15 @@ Debian-based:
:: ::
sudo apt-get install clang-format apt-cache search clang-format
Above will list all the versions available. Pick the newest one
available (3.9 for Ubuntu 16.10 as I write this) and install it:
::
sudo apt-get install clang-format-3.9
sudo ln -s /usr/bin/clang-format-3.9 /usr/bin/clang-format
Message Translations Message Translations
-------------------- --------------------
@@ -404,19 +476,14 @@ stored in the ``po`` directory, named ``LANG.po``, where ``LANG`` is the
two letter ISO 639-1 language code of the target language (eg ``de`` for two letter ISO 639-1 language code of the target language (eg ``de`` for
German). German).
To create a new translation, for example for German: To create a new translation, for example for German: \* generate a
``messages.pot`` file by running ``build_tools/fish_xgettext.fish`` from
the source tree \* copy ``messages.pot`` to ``po/LANG.po`` ()
* generate a ``messages.pot`` file by running ``build_tools/fish_xgettext.fish`` from To update a translation: \* generate a ``messages.pot`` file by running
the source tree ``build_tools/fish_xgettext.fish`` from the source tree \* update the
* copy ``messages.pot`` to ``po/LANG.po`` existing translation by running
``msgmerge --update --no-fuzzy-matching po/LANG.po messages.pot``
To update a translation:
* generate a ``messages.pot`` file by running
``build_tools/fish_xgettext.fish`` from the source tree
* update the existing translation by running
``msgmerge --update --no-fuzzy-matching po/LANG.po messages.pot``
Many tools are available for editing translation files, including Many tools are available for editing translation files, including
command-line and graphical user interface programs. command-line and graphical user interface programs.
@@ -430,46 +497,3 @@ recommended deletions.
Read the `translations Read the `translations
wiki <https://github.com/fish-shell/fish-shell/wiki/Translations>`__ for wiki <https://github.com/fish-shell/fish-shell/wiki/Translations>`__ for
more information. more information.
Versioning
----------
The fish version is constructed by the *build_tools/git_version_gen.sh*
script. For developers the version is the branch name plus the output of
``git describe --always --dirty``. Normally the main part of the version
will be the closest annotated tag. Which itself is usually the most
recent release number (e.g., ``2.6.0``).
Include What You Use
--------------------
You should not depend on symbols being visible to a ``*.cpp`` module
from ``#include`` statements inside another header file. In other words
if your module does ``#include "common.h"`` and that header does
``#include "signal.h"`` your module should not assume the sub-include is
present. It should instead directly ``#include "signal.h"`` if it needs
any symbol from that header. That makes the actual dependencies much
clearer. It also makes it easy to modify the headers included by a
specific header file without having to worry that will break any module
(or header) that includes a particular header.
To help enforce this rule the ``make lint`` (and ``make lint-all``)
command will run the
`include-what-you-use <https://include-what-you-use.org/>`__ tool. You
can find the IWYU project on
`github <https://github.com/include-what-you-use/include-what-you-use>`__.
To install the tool on OS X youll need to add a
`formula <https://github.com/jasonmp85/homebrew-iwyu>`__ then install
it:
::
brew tap jasonmp85/iwyu
brew install iwyu
On Ubuntu you can install it via ``apt-get``:
::
sudo apt-get install iwyu

View File

@@ -1,7 +1,7 @@
Fish is a smart and user-friendly command line shell. Fish is a smart and user-friendly command line shell.
Copyright (C) 2005-2009 Axel Liljencrantz Copyright (C) 2005-2009 Axel Liljencrantz
Copyright (C) 2009-2022 fish-shell contributors Copyright (C) 2009-2020 fish-shell contributors
fish is free software. fish is free software.
@@ -12,7 +12,7 @@ published by the Free Software Foundation.
fish also includes software licensed under the GNU Lesser General Public fish also includes software licensed under the GNU Lesser General Public
License version 2, the OpenBSD license, the ISC license, and the NetBSD license. License version 2, the OpenBSD license, the ISC license, and the NetBSD license.
Full licensing information is contained in doc_src/license.rst. Full licensing information is contained in doc_src/license.hdr.
This program is distributed in the hope that it will be useful, but WITHOUT This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or

View File

@@ -31,19 +31,16 @@ else
all: .begin build/fish all: .begin build/fish
.PHONY: .begin PHONY: .begin
.begin: .begin:
@which $(CMAKE) > /dev/null 2> /dev/null || \ @which $(CMAKE) > /dev/null 2> /dev/null || \
(echo 'Please install CMake and then re-run the `make` command!' 1>&2 && false) (echo 'Please install CMake and then re-run the `make` command!' 1>&2 && false)
.PHONY: build/fish
build/fish: build/$(BUILDFILE) build/fish: build/$(BUILDFILE)
$(CMAKE) --build build $(CMAKE) --build build
# Use build as an order-only dependency. This prevents the target from always being outdated build/$(BUILDFILE): build
# after a make run, and more importantly, doesn't clobber manually specified CMake options. cd build; $(CMAKE) .. -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -G "$(GENERATOR)" \
build/$(BUILDFILE): | build
cd build; $(CMAKE) .. -G "$(GENERATOR)" \
-DCMAKE_INSTALL_PREFIX="$(PREFIX)" -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_INSTALL_PREFIX="$(PREFIX)" -DCMAKE_EXPORT_COMPILE_COMMANDS=1
build: build:

View File

@@ -20,6 +20,11 @@ magic phrase “unlike other shells”.
Detailed user documentation is available by running ``help`` within Detailed user documentation is available by running ``help`` within
fish, and also at https://fishshell.com/docs/current/index.html fish, and also at https://fishshell.com/docs/current/index.html
You can quickly play with fish right in your browser by clicking the
button below:
|Try in browser|
Getting fish Getting fish
------------ ------------
@@ -48,8 +53,8 @@ and can be installed using the following commands:
:: ::
sudo apt-add-repository ppa:fish-shell/release-3 sudo apt-add-repository ppa:fish-shell/release-3
sudo apt update sudo apt-get update
sudo apt install fish sudo apt-get install fish
Instructions for other distributions may be found at Instructions for other distributions may be found at
`fishshell.com <https://fishshell.com>`__. `fishshell.com <https://fishshell.com>`__.
@@ -71,7 +76,7 @@ If packages are not available for your platform, GPG-signed tarballs are
available from `fishshell.com <https://fishshell.com/>`__ and available from `fishshell.com <https://fishshell.com/>`__ and
`fish-shell on `fish-shell on
GitHub <https://github.com/fish-shell/fish-shell/releases>`__. See the GitHub <https://github.com/fish-shell/fish-shell/releases>`__. See the
`Building <#building>`__ section for instructions. *Building* section for instructions.
Running fish Running fish
------------ ------------
@@ -87,9 +92,9 @@ Running fish requires:
- some common \*nix system utilities (currently ``mktemp``), in - some common \*nix system utilities (currently ``mktemp``), in
addition to the basic POSIX utilities (``cat``, ``cut``, ``dirname``, addition to the basic POSIX utilities (``cat``, ``cut``, ``dirname``,
``ls``, ``mkdir``, ``mkfifo``, ``rm``, ``sort``, ``tee``, ``tr``, ``ls``, ``mkdir``, ``mkfifo``, ``rm``, ``sort``, ``tee``, ``tr``,
``uname`` and ``sed`` at least, but the full coreutils plus ``find`` and ``uname`` and ``sed`` at least, but the full coreutils plus find, sed
``awk`` is preferred) and awk is preferred)
- The gettext library, if compiled with - gettext (library and ``gettext`` command), if compiled with
translation support translation support
The following optional features also have specific requirements: The following optional features also have specific requirements:
@@ -97,15 +102,16 @@ The following optional features also have specific requirements:
- builtin commands that have the ``--help`` option or print usage - builtin commands that have the ``--help`` option or print usage
messages require ``ul`` and either ``nroff`` or ``mandoc`` for messages require ``ul`` and either ``nroff`` or ``mandoc`` for
display display
- automated completion generation from manual pages requires Python 3.5+ - automated completion generation from manual pages requires Python
- the ``fish_config`` web configuration tool requires Python 3.5+ and a web browser (2.7+ or 3.3+) and possibly the ``backports.lzma`` module for Python
2.7
- the ``fish_config`` web configuration tool requires Python (2.7+ or
3.3 +) and a web browser
- system clipboard integration (with the default Ctrl-V and Ctrl-X - system clipboard integration (with the default Ctrl-V and Ctrl-X
bindings) require either the ``xsel``, ``xclip``, bindings) require either the ``xsel``, ``xclip``,
``wl-copy``/``wl-paste`` or ``pbcopy``/``pbpaste`` utilities ``wl-copy``/``wl-paste`` or ``pbcopy``/``pbpaste`` utilities
- full completions for ``yarn`` and ``npm`` require the - full completions for ``yarn`` and ``npm`` require the
``all-the-package-names`` NPM module ``all-the-package-names`` NPM module
- ``colorls`` is used, if installed, to add color when running ``ls`` on platforms
that do not have color support (such as OpenBSD)
Switching to fish Switching to fish
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
@@ -144,7 +150,7 @@ Dependencies
Compiling fish requires: Compiling fish requires:
- a C++11 compiler (g++ 4.8 or later, or clang 3.3 or later) - a C++11 compiler (g++ 4.8 or later, or clang 3.3 or later)
- CMake (version 3.5 or later) - CMake (version 3.2 or later)
- a curses implementation such as ncurses (headers and libraries) - a curses implementation such as ncurses (headers and libraries)
- PCRE2 (headers and libraries) - a copy is included with fish - PCRE2 (headers and libraries) - a copy is included with fish
- gettext (headers and libraries) - optional, for translation support - gettext (headers and libraries) - optional, for translation support
@@ -152,8 +158,6 @@ Compiling fish requires:
Sphinx is also optionally required to build the documentation from a Sphinx is also optionally required to build the documentation from a
cloned git repository. cloned git repository.
Additionally, running the test suite requires Python 3.5+ and the pexpect package.
Building from source (all platforms) - Makefile generator Building from source (all platforms) - Makefile generator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -189,19 +193,6 @@ You can open it with Xcode, or run the following to build and install in
The install directory can be changed using the The install directory can be changed using the
``-DCMAKE_INSTALL_PREFIX`` parameter for ``cmake``. ``-DCMAKE_INSTALL_PREFIX`` parameter for ``cmake``.
Build options
~~~~~~~~~~~~~
In addition to the normal cmake build options (like ``CMAKE_INSTALL_PREFIX``), fish has some other options available to customize it.
- BUILD_DOCS=ON|OFF - whether to build the documentation. This is automatically set to OFF when sphinx isn't installed.
- INSTALL_DOCS=ON|OFF - whether to install the docs. This is automatically set to on when BUILD_DOCS is or prebuilt documentation is available (like when building in-tree from a tarball).
- FISH_USE_SYSTEM_PCRE2=ON|OFF - whether to use an installed pcre2. This is normally autodetected.
- MAC_CODESIGN_ID=String|OFF - the codesign ID to use on Mac, or "OFF" to disable codesigning.
- WITH_GETTEXT=ON|OFF - whether to build with gettext support for translations.
Note that fish does *not* support static linking and will attempt to error out if it detects it.
Help, it didnt build! Help, it didnt build!
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
@@ -212,7 +203,7 @@ On Debian or Ubuntu you want:
:: ::
sudo apt install build-essential cmake ncurses-dev libncurses5-dev libpcre2-dev gettext sudo apt-get install build-essential cmake ncurses-dev libncurses5-dev libpcre2-dev gettext
On RedHat, CentOS, or Amazon EC2: On RedHat, CentOS, or Amazon EC2:
@@ -231,12 +222,17 @@ Contact Us
Questions, comments, rants and raves can be posted to the official fish Questions, comments, rants and raves can be posted to the official fish
mailing list at https://lists.sourceforge.net/lists/listinfo/fish-users mailing list at https://lists.sourceforge.net/lists/listinfo/fish-users
or join us on our `gitter.im or join us on our `gitter.im
channel <https://gitter.im/fish-shell/fish-shell>`__. Or use the `fish tag channel <https://gitter.im/fish-shell/fish-shell>`__. Or use the `fish
on Unix & Linux Stackexchange <https://unix.stackexchange.com/questions/tagged/fish>`__. tag on
There is also a fish tag on Stackoverflow, but it is typically a poor fit. Stackoverflow <https://stackoverflow.com/questions/tagged/fish>`__ for
questions related to fish script and the `fish tag on
Superuser <https://superuser.com/questions/tagged/fish>`__ for all other
questions (e.g., customizing colors, changing key bindings).
Found a bug? Have an awesome idea? Please `open an Found a bug? Have an awesome idea? Please `open an
issue <https://github.com/fish-shell/fish-shell/issues/new>`__. issue <https://github.com/fish-shell/fish-shell/issues/new>`__.
.. |Build Status| image:: https://github.com/fish-shell/fish-shell/workflows/make%20test/badge.svg .. |Build Status| image:: https://travis-ci.org/fish-shell/fish-shell.svg?branch=master
:target: https://github.com/fish-shell/fish-shell/actions :target: https://travis-ci.org/fish-shell/fish-shell
.. |Try in browser| image:: https://cdn.rawgit.com/rootnroll/library/assets/try.svg
:target: https://rootnroll.com/d/fish-shell/

View File

@@ -1089,3 +1089,4 @@ alias alias1020='something --arg1020'
alias alias1021='something --arg1021' alias alias1021='something --arg1021'
alias alias1022='something --arg1022' alias alias1022='something --arg1022'
alias alias1023='something --arg1023' alias alias1023='something --arg1023'

View File

@@ -1,3 +1,4 @@
for i in (seq 2000) for i in (seq 2000)
command true command true
end end

View File

@@ -1,8 +0,0 @@
# Glob fish's source directory.
# This timing is bound to change if the repo does,
# so it's best to build two fishes, check out one version of the repo,
# and then run this script with both.
set -l dir (dirname (status current-filename))
for i in (seq 1 100)
echo $dir/../../**
end

View File

@@ -1,3 +0,0 @@
for i in (seq 100000)
math $i + $i
end

View File

@@ -1,3 +1,3 @@
for i in (seq 10000) for i in (seq 1000)
echo $i echo $i
end end

View File

@@ -1,41 +1,17 @@
#!/bin/sh #!/bin/sh
if [ "$#" -gt 2 -o "$#" -eq 0 ]; then if [ "$#" -ne 1 ]; then
echo "Usage: driver.sh /path/to/fish [/path/to/other/fish]" echo "Usage: driver.sh /path/to/fish"
exit 1
fi fi
FISH_PATH=$1 FISH_PATH=$1
FISH2_PATH=$2
BENCHMARKS_DIR=$(dirname "$0")/benchmarks BENCHMARKS_DIR=$(dirname "$0")/benchmarks
quote() {
# Single-quote the given string for a POSIX shell, except in common cases that don't need it.
printf %s "$1" |
sed "/[^[:alnum:]\/.-]/ {
s/'/'\\\''/g
s/^/'/
s/\$/'/
}"
}
for benchmark in "$BENCHMARKS_DIR"/*; do for benchmark in "$BENCHMARKS_DIR"/*; do
basename "$benchmark" basename "$benchmark"
[ -n "$FISH2_PATH" ] && echo "$FISH_PATH" ${FISH_PATH} --print-rusage-self "$benchmark" > /dev/null
"${FISH_PATH}" --print-rusage-self "$benchmark" > /dev/null
if [ -n "$FISH2_PATH" ]; then
echo "$FISH2_PATH"
"${FISH2_PATH}" --print-rusage-self "$benchmark" > /dev/null
fi
if command -v hyperfine >/dev/null 2>&1; then if command -v hyperfine >/dev/null 2>&1; then
cmd1="$(quote "${FISH_PATH}") $(quote "$benchmark") > /dev/null" hyperfine "${FISH_PATH} $benchmark > /dev/null"
if [ -n "$FISH2_PATH" ]; then
cmd2="$(quote "${FISH2_PATH}") $(quote "$benchmark") > /dev/null"
hyperfine "$cmd1" "$cmd2"
else
hyperfine "$cmd1"
fi
fi fi
done done

View File

@@ -1,7 +1,3 @@
#!/bin/sh #!/usr/local/bin/fish
cppcheck --std=c++11 --quiet \ cppcheck --enable=all --std=posix --quiet ./src/
--suppressions-list=build_tools/cppcheck.suppressions --inline-suppr \
--rule-file=build_tools/cppcheck.rules \
--force \
${@:---enable=all ./src/}

View File

@@ -1,23 +0,0 @@
#!/usr/bin/env fish
# Build a list of all sections in the html sphinx docs, separately by page,
# so it can be added to share/functions/help.fish
# Use like
# fish extract_help_sections.fish user_doc/html/{fish_for_bash_users.html,faq.html,interactive.html,language.html,tutorial.html}
# TODO: Currently `help` uses variable names we can't generate, so it needs to be touched up manually.
# Also this could easily be broken by changes in sphinx, ideally we'd have a way to let it print the section titles.
#
for file in $argv
set -l varname (string replace -r '.*/(.*).html' '$1' -- $file | string escape --style=var)pages
# Technically we can use any id in the document as an anchor, but listing them all is probably too much.
# Sphinx stores section titles (in a slug-ized form) in the id,
# and stores explicit section links in a `span` tag like
# `<span id="identifiers"></span>`
# We extract both separately.
set -l sections (string replace -rf '.*class="headerlink" href="#([^"]*)".*' '$1' <$file)
# Sections titled "id5" and such are internal cruft and shouldn't be offered.
set -a sections (string replace -rf '.*span id="([^"]*)".*' '$1' <$file | string match -rv 'id\d+')
set sections (printf '%s\n' $sections | sort -u)
echo set -l $varname $sections
end

View File

@@ -14,7 +14,8 @@ set -g whitelist \
# unclear what this is \ # unclear what this is \
l_constinit \ l_constinit \
# hacks to work around missing ncurses strings on mac \ # hacks to work around missing ncurses strings on mac \
sitm_esc ritm_esc dim_esc sitm_esc ritm_esc dim_esc \
# In our nm regex, we are interested in data (dD) and bss (bB) segments. # In our nm regex, we are interested in data (dD) and bss (bB) segments.
set -g nm_regex '^([^ ]+) ([dDbB])' set -g nm_regex '^([^ ]+) ([dDbB])'
@@ -23,7 +24,8 @@ set -l total_globals 0
set -l boring_files \ set -l boring_files \
fish_key_reader.cpp.o \ fish_key_reader.cpp.o \
fish_tests.cpp.o \ fish_tests.cpp.o \
fish_indent.cpp.o fish_indent.cpp.o \
# return if we should ignore the given symbol name # return if we should ignore the given symbol name
function should_ignore function should_ignore

View File

@@ -1,63 +0,0 @@
#!/usr/bin/env python3
# Finds potential ODR violations due to weak symbols.
# For example, if you have two different structs with the same name in different files,
# their inline constructors may collide.
# This works only on Linux. It is designed to be run from the cmake build directory.
# clang seems more willing to emit non-inlined ctors. Of course perform a Debug build.
import re
import subprocess
output = subprocess.check_output(
"nm --radix=d -g --demangle -l --print-size CMakeFiles/fishlib.dir/src/*.o",
shell=True,
universal_newlines=True,
)
files_by_name = {} # Symbol to set of paths
sizes_by_name = {} # Symbol to set of int sizes
for line in output.split("\n"):
# Keep only weak symbols with default values (e.g. emitted inline functions).
# Example line: "0000000000000000 0000000000000107 W symbol_name"
# First number is offset, second is size.
# Note this is decimal because of radix=d.
m = re.match(r"\d+ (\d+) W (.*)\t(.*)", line)
if not m:
continue
size, name, filename = m.groups()
files_by_name.setdefault(name, set()).add(filename)
sizes_by_name.setdefault(name, set()).add(int(size))
odr_violations = 0
for name, sizes in sizes_by_name.items():
if len(sizes) == 1:
continue
files = files_by_name[name]
# Ignore symbols that only appear in one file.
# These are typically headers - unclear why they get different sizes but it appears benign.
if len(files) == 1:
continue
# Multiple sizes for this symbol name.
odr_violations += 1
print("Multiple sizes for symbol: " + name)
print("\t%s" % ", ".join([str(x) for x in sizes]))
print("\tFound in files:")
for filename in files:
print("\t\t%s" % filename)
if odr_violations == 0:
print("No ODR violations found, hooray\n")
# Show potential weak symbols.
suspicious_odrs = 0
for (name, files) in files_by_name.items():
if len(files) != 1:
continue
(filename,) = files
if ".cpp" in filename:
if suspicious_odrs == 0:
print("Some suspicious singles:")
suspicious_odrs += 1
print("\t%s" % name)
print("\t\tIn file %s" % filename)

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env fish #!/usr/bin/env fish
# #
# Tool to generate messages.pot # Tool to generate messages.pot
# Extended to replace the old Makefile rule which did not port easily to CMake # Extended to replace the old Makefile rule which did not port easily to CMak
# This script was originally motivated to work around a quirk (or bug depending on your viewpoint) # This script was originally motivated to work around a quirk (or bug depending on your viewpoint)
# of the xgettext command. See https://lists.gnu.org/archive/html/bug-gettext/2014-11/msg00006.html. # of the xgettext command. See https://lists.gnu.org/archive/html/bug-gettext/2014-11/msg00006.html.
@@ -22,39 +22,34 @@ set -l implicit_regex '(?:^| +)(?:complete|function).*? (?:-d|--description) (([
# than messages which should be implicitly translated. # than messages which should be implicitly translated.
set -l explicit_regex '.*\( *_ (([\'"]).+?(?<!\\\\)\\2) *\).*' set -l explicit_regex '.*\( *_ (([\'"]).+?(?<!\\\\)\\2) *\).*'
# Create temporary directory for these operations. OS X `mktemp` is somewhat restricted, so this block rm -r /tmp/fish
# works around that - based on share/functions/funced.fish.
set -q TMPDIR
or set -l TMPDIR /tmp
set -l tmpdir (mktemp -d $TMPDIR/fish.XXXXXX)
or exit 1
mkdir -p $tmpdir/implicit/share/completions $tmpdir/implicit/share/functions mkdir -p /tmp/fish/implicit/share/completions /tmp/fish/implicit/share/functions
mkdir -p $tmpdir/explicit/share/completions $tmpdir/explicit/share/functions mkdir -p /tmp/fish/explicit/share/completions /tmp/fish/explicit/share/functions
for f in share/config.fish share/completions/*.fish share/functions/*.fish for f in share/config.fish share/completions/*.fish share/functions/*.fish
# Extract explicit attempts to translate a message. That is, those that are of the form # Extract explicit attempts to translate a message. That is, those that are of the form
# `(_ "message")`. # `(_ "message")`.
string replace --filter --regex $explicit_regex 'echo $1' <$f | fish >$tmpdir/explicit/$f.tmp 2>/dev/null string replace --filter --regex $explicit_regex 'echo $1' <$f | fish >/tmp/fish/explicit/$f.tmp ^/dev/null
while read description while read description
echo 'N_ "'(string replace --all '"' '\\"' -- $description)'"' echo 'N_ "'(string replace --all '"' '\\"' -- $description)'"'
end <$tmpdir/explicit/$f.tmp >$tmpdir/explicit/$f end </tmp/fish/explicit/$f.tmp >/tmp/fish/explicit/$f
rm $tmpdir/explicit/$f.tmp rm /tmp/fish/explicit/$f.tmp
# Handle `complete` / `function` description messages. The `| fish` is subtle. It basically # Handle `complete` / `function` description messages. The `| fish` is subtle. It basically
# avoids the need to use `source` with a command substitution that could affect the current # avoids the need to use `source` with a command substitution that could affect the current
# shell. # shell.
string replace --filter --regex $implicit_regex 'echo $1' <$f | fish >$tmpdir/implicit/$f.tmp 2>/dev/null string replace --filter --regex $implicit_regex 'echo $1' <$f | fish >/tmp/fish/implicit/$f.tmp ^/dev/null
while read description while read description
# We don't use `string escape` as shown in the next comment because it produces output that # We don't use `string escape` as shown in the next comment because it produces output that
# is not parsed correctly by xgettext. Instead just escape double-quotes and quote the # is not parsed correctly by xgettext. Instead just escape double-quotes and quote the
# resulting string. # resulting string.
echo 'N_ "'(string replace --all '"' '\\"' -- $description)'"' echo 'N_ "'(string replace --all '"' '\\"' -- $description)'"'
end <$tmpdir/implicit/$f.tmp >$tmpdir/implicit/$f end </tmp/fish/implicit/$f.tmp >/tmp/fish/implicit/$f
rm $tmpdir/implicit/$f.tmp rm /tmp/fish/implicit/$f.tmp
end end
xgettext -j -k -kN_ -LShell --from-code=UTF-8 -cDescription --no-wrap -o messages.pot $tmpdir/explicit/share/*/*.fish xgettext -j -k -kN_ -LShell --from-code=UTF-8 -cDescription --no-wrap -o messages.pot /tmp/fish/explicit/share/*/*.fish
xgettext -j -k -kN_ -LShell --from-code=UTF-8 -cDescription --no-wrap -o messages.pot $tmpdir/implicit/share/*/*.fish xgettext -j -k -kN_ -LShell --from-code=UTF-8 -cDescription --no-wrap -o messages.pot /tmp/fish/implicit/share/*/*.fish
rm -r $tmpdir rm -r /tmp/fish

View File

@@ -1,4 +1,4 @@
#!/bin/sh #!/usr/bin/env sh
# Originally from the git sources (GIT-VERSION-GEN) # Originally from the git sources (GIT-VERSION-GEN)
# Presumably (C) Junio C Hamano <junkio@cox.net> # Presumably (C) Junio C Hamano <junkio@cox.net>
# Reused under GPL v2.0 # Reused under GPL v2.0
@@ -28,11 +28,11 @@ fi
# Set the output directory as either the first param or cwd. # Set the output directory as either the first param or cwd.
test -n "$1" && OUTPUT_DIR=$1/ || OUTPUT_DIR= test -n "$1" && OUTPUT_DIR=$1/ || OUTPUT_DIR=
FBVF="${OUTPUT_DIR}FISH-BUILD-VERSION-FILE" FBVF=${OUTPUT_DIR}FISH-BUILD-VERSION-FILE
if test -r "$FBVF" if test -r $FBVF
then then
VC=$(grep -v '^#' "$FBVF" | tr -d '"' | sed -e 's/^FISH_BUILD_VERSION=//') VC=$(grep -v '^#' $FBVF | tr -d '"' | sed -e 's/^FISH_BUILD_VERSION=//')
else else
VC="unset" VC="unset"
fi fi
@@ -41,7 +41,7 @@ fi
# It looks like FISH_BUILD_VERSION="2.7.1-621-ga2f065e6" # It looks like FISH_BUILD_VERSION="2.7.1-621-ga2f065e6"
test "$VN" = "$VC" || { test "$VN" = "$VC" || {
echo >&2 "FISH_BUILD_VERSION=$VN" echo >&2 "FISH_BUILD_VERSION=$VN"
echo "FISH_BUILD_VERSION=\"$VN\"" >"$FBVF" echo "FISH_BUILD_VERSION=\"$VN\"" >${FBVF}
} }
# Output the fish-build-version-witness.txt # Output the fish-build-version-witness.txt

View File

@@ -18,11 +18,11 @@ argparse a/all p/project= -- $argv
# We only want -D and -I options to be passed thru to cppcheck. # We only want -D and -I options to be passed thru to cppcheck.
for arg in $argv for arg in $argv
if string match -q -- '-D*' $arg if string match -q -- '-D*' $arg
set -a cppcheck_args (string split -- ' ' $arg) set cppcheck_args $cppcheck_args $arg
else if string match -q -- '-I*' $arg else if string match -q -- '-I*' $arg
set -a cppcheck_args (string split -- ' ' $arg) set cppcheck_args $cppcheck_args $arg
else if string match -q -- '-iquote*' $arg else if string match -q -- '-iquote*' $arg
set -a cppcheck_args (string split -- ' ' $arg) set cppcheck_args $cppcheck_args $arg
end end
end end
@@ -83,7 +83,20 @@ if set -q c_files[1]
echo ======================================== echo ========================================
echo Running cppcheck echo Running cppcheck
echo ======================================== echo ========================================
build_tools/cppcheck.sh --enable=$cppchecks $c_files 2>&1 # The stderr to stdout redirection is because cppcheck, incorrectly IMHO, writes its
# diagnostic messages to stderr. Anyone running this who wants to capture its output will
# expect those messages to be written to stdout.
set -l cn (set_color normal)
set -l cb (set_color --bold)
set -l cu (set_color --underline)
set -l cm (set_color magenta)
set -l cbrm (set_color brmagenta)
set -l template "[$cb$cu{file}$cn$cb:{line}$cn] $cbrm{severity}$cm ({id}):$cn\n {message}"
set cppcheck_args -q --verbose --std=c++11 --std=posix --language=c++ --template $template \
--suppress=missingIncludeSystem --inline-suppr --enable=$cppchecks \
--rule-file=.cppcheck.rules --suppressions-list=.cppcheck.suppressions $cppcheck_args
cppcheck $cppcheck_args $c_files 2>&1
echo echo
echo ======================================== echo ========================================

View File

@@ -13,9 +13,7 @@ if not contains -- $TAG (git tag)
end end
set -l committers_to_tag (mktemp) set -l committers_to_tag (mktemp)
or exit 1
set -l committers_from_tag (mktemp) set -l committers_from_tag (mktemp)
or exit 1
# You might think it would be better to case-insensitively sort/compare the names # You might think it would be better to case-insensitively sort/compare the names
# to produce a more natural-looking list. # to produce a more natural-looking list.

View File

@@ -6,6 +6,7 @@ from __future__ import unicode_literals
from __future__ import print_function from __future__ import print_function
import argparse import argparse
from collections import deque
import datetime import datetime
import io import io
import re import re
@@ -13,39 +14,15 @@ import shlex
import subprocess import subprocess
import sys import sys
try:
from itertools import zip_longest
except ImportError:
from itertools import izip_longest as zip_longest
from difflib import SequenceMatcher
# Directives can occur at the beginning of a line, or anywhere in a line that does not start with #.
COMMENT_RE = r"^(?:[^#].*)?#\s*"
# A regex showing how to run the file. # A regex showing how to run the file.
RUN_RE = re.compile(COMMENT_RE + r"RUN:\s+(.*)\n") RUN_RE = re.compile(r"\s*#\s*RUN:\s+(.*)\n")
REQUIRES_RE = re.compile(COMMENT_RE + r"REQUIRES:\s+(.*)\n")
# A regex capturing lines that should be checked against stdout. # A regex capturing lines that should be checked against stdout.
CHECK_STDOUT_RE = re.compile(COMMENT_RE + r"CHECK:\s+(.*)\n") CHECK_STDOUT_RE = re.compile(r"\s*#\s*CHECK:\s+(.*)\n")
# A regex capturing lines that should be checked against stderr. # A regex capturing lines that should be checked against stderr.
CHECK_STDERR_RE = re.compile(COMMENT_RE + r"CHECKERR:\s+(.*)\n") CHECK_STDERR_RE = re.compile(r"\s*#\s*CHECKERR:\s+(.*)\n")
SKIP = object()
def find_command(program):
import os
path, name = os.path.split(program)
if path:
return os.path.isfile(program) and os.access(program, os.X_OK)
for path in os.environ["PATH"].split(os.pathsep):
exe = os.path.join(path, program)
if os.path.isfile(exe) and os.access(exe, os.X_OK):
return exe
return None
class Config(object): class Config(object):
def __init__(self): def __init__(self):
@@ -55,6 +32,10 @@ class Config(object):
self.colorize = False self.colorize = False
# Whether to show which file was tested. # Whether to show which file was tested.
self.progress = False self.progress = False
# How many after lines to print
self.after = 5
# How many before lines to print
self.before = 5
def colors(self): def colors(self):
""" Return a dictionary mapping color names to ANSI escapes """ """ Return a dictionary mapping color names to ANSI escapes """
@@ -137,26 +118,6 @@ class Line(object):
self.number = number self.number = number
self.file = file self.file = file
def __hash__(self):
# Chosen by fair diceroll
# No, just kidding.
# HACK: We pass this to the Sequencematcher, which puts the Checks into a dict.
# To force it to match the regexes, we return a hash collision intentionally,
# so it falls back on __eq__().
#
# CheckCmd has the same thing.
return 0
def __eq__(self, other):
if other is None:
return False
if isinstance(other, CheckCmd):
return other.regex.match(self.text)
if isinstance(other, Line):
# We only compare the text here so SequenceMatcher can reshuffle these
return self.text == other.text
raise NotImplementedError
def subline(self, text): def subline(self, text):
""" Return a substring of our line with the given text, preserving number and file. """ """ Return a substring of our line with the given text, preserving number and file. """
return Line(text, self.number, self.file) return Line(text, self.number, self.file)
@@ -168,16 +129,10 @@ class Line(object):
def is_empty_space(self): def is_empty_space(self):
return not self.text or self.text.isspace() return not self.text or self.text.isspace()
def escaped_text(self, for_formatting=False):
ret = escape_string(self.text.rstrip("\n"))
if for_formatting:
ret = ret.replace("{", "{{").replace("}", "}}")
return ret
class RunCmd(object): class RunCmd(object):
"""A command to run on a given Checker. """ A command to run on a given Checker.
Attributes: Attributes:
args: Unexpanded shell command as a string. args: Unexpanded shell command as a string.
""" """
@@ -194,16 +149,17 @@ class RunCmd(object):
class TestFailure(object): class TestFailure(object):
def __init__(self, line, check, testrun, diff=None, lines=[], checks=[]): def __init__(self, line, check, testrun, before=None, after=None):
self.line = line self.line = line
self.check = check self.check = check
self.testrun = testrun self.testrun = testrun
self.error_annotation_lines = None self.error_annotation_line = None
self.diff = diff # The output that comes *after* the failure.
self.lines = lines self.after = after
self.checks = checks self.before = before
def message(self): def message(self):
afterlines = self.testrun.config.after
fields = self.testrun.config.colors() fields = self.testrun.config.colors()
fields["name"] = self.testrun.name fields["name"] = self.testrun.name
fields["subbed_command"] = self.testrun.subbed_command fields["subbed_command"] = self.testrun.subbed_command
@@ -212,7 +168,7 @@ class TestFailure(object):
{ {
"output_file": self.line.file, "output_file": self.line.file,
"output_lineno": self.line.number, "output_lineno": self.line.number,
"output_line": self.line.escaped_text(), "output_line": self.line.text.rstrip("\n"),
} }
) )
if self.check: if self.check:
@@ -220,7 +176,7 @@ class TestFailure(object):
{ {
"input_file": self.check.line.file, "input_file": self.check.line.file,
"input_lineno": self.check.line.number, "input_lineno": self.check.line.number,
"input_line": self.check.line.escaped_text(), "input_line": self.check.line.text,
"check_type": self.check.type, "check_type": self.check.type,
} }
) )
@@ -250,97 +206,24 @@ class TestFailure(object):
" {BOLD}{output_line}{RESET}", " {BOLD}{output_line}{RESET}",
"", "",
] ]
if self.error_annotation_lines: if self.error_annotation_line:
fields["error_annotation"] = " ".join( fields["error_annotation"] = self.error_annotation_line.text
[x.text for x in self.error_annotation_lines] fields["error_annotation_lineno"] = self.error_annotation_line.number
)
fields["error_annotation_lineno"] = str(
self.error_annotation_lines[0].number
)
if len(self.error_annotation_lines) > 1:
fields["error_annotation_lineno"] += ":" + str(
self.error_annotation_lines[-1].number
)
fmtstrs += [ fmtstrs += [
" additional output on stderr:{error_annotation_lineno}:", " additional output on stderr:{error_annotation_lineno}:",
" {BOLD}{error_annotation}{RESET}", " {BOLD}{error_annotation}{RESET}",
] ]
if self.diff: if self.before:
fmtstrs += [" Context:"] fields["before_output"] = " ".join(self.before)
lasthi = 0 fields["additional_output"] = " ".join(self.after[:afterlines])
lastcheckline = None fmtstrs += [
for d in self.diff.get_grouped_opcodes(): " Context:",
for op, alo, ahi, blo, bhi in d: " {BOLD}{before_output} {RED}{output_line}{RESET} <= does not match '{LIGHTBLUE}{input_line}{RESET}'",
color = "{BOLD}" " {BOLD}{additional_output}{RESET}",
if op == "replace" or op == "delete": ]
color = "{RED}" elif self.after:
# We got a new chunk, so we print a marker. fields["additional_output"] = " ".join(self.after[:afterlines])
if alo > lasthi: fmtstrs += [" additional output:", " {BOLD}{additional_output}{RESET}"]
fmtstrs += [
" [...] from line "
+ str(self.checks[blo].line.number)
+ " ("
+ self.lines[alo].file
+ ":"
+ str(self.lines[alo].number)
+ "):"
]
lasthi = ahi
# We print one "no more checks" after the last check and then skip any markers
lastcheck = False
for a, b in zip_longest(self.lines[alo:ahi], self.checks[blo:bhi]):
# Clean up strings for use in a format string - double up the curlies.
astr = (
color + a.escaped_text(for_formatting=True) + "{RESET}"
if a
else ""
)
if b:
bstr = (
"'{BLUE}"
+ b.line.escaped_text(for_formatting=True)
+ "{RESET}'"
+ " on line "
+ str(b.line.number)
)
lastcheckline = b.line.number
if op == "equal":
fmtstrs += [" " + astr]
elif b and a:
fmtstrs += [
" "
+ astr
+ " <= does not match "
+ b.type
+ " "
+ bstr
]
elif b:
fmtstrs += [
" "
+ astr
+ " <= nothing to match "
+ b.type
+ " "
+ bstr
]
elif not b:
string = " " + astr
if bhi == len(self.checks):
if not lastcheck:
string += " <= no more checks"
lastcheck = True
elif lastcheckline is not None:
string += (
" <= no check matches this, previous check on line "
+ str(lastcheckline)
)
else:
string += " <= no check matches"
fmtstrs.append(string)
fmtstrs.append("")
fmtstrs += [" when running command:", " {subbed_command}"] fmtstrs += [" when running command:", " {subbed_command}"]
return "\n".join(fmtstrs).format(**fields) return "\n".join(fmtstrs).format(**fields)
@@ -350,8 +233,8 @@ class TestFailure(object):
def perform_substitution(input_str, subs): def perform_substitution(input_str, subs):
"""Perform the substitutions described by subs to str """ Perform the substitutions described by subs to str
Return the substituted string. Return the substituted string.
""" """
# Sort our substitutions into a list of tuples (key, value), descending by length. # Sort our substitutions into a list of tuples (key, value), descending by length.
# It needs to be descending because we need to try longer substitutions first. # It needs to be descending because we need to try longer substitutions first.
@@ -371,20 +254,6 @@ def perform_substitution(input_str, subs):
return re.sub(r"%(%|[a-zA-Z0-9_-]+)", subber, input_str) return re.sub(r"%(%|[a-zA-Z0-9_-]+)", subber, input_str)
def runproc(cmd):
""" Wrapper around subprocess.Popen to save typing """
PIPE = subprocess.PIPE
proc = subprocess.Popen(
cmd,
stdin=PIPE,
stdout=PIPE,
stderr=PIPE,
shell=True,
close_fds=True, # For Python 2.6 as shipped on RHEL 6
)
return proc
class TestRun(object): class TestRun(object):
def __init__(self, name, runcmd, checker, subs, config): def __init__(self, name, runcmd, checker, subs, config):
self.name = name self.name = name
@@ -398,89 +267,74 @@ class TestRun(object):
# Reverse our lines and checks so we can pop off the end. # Reverse our lines and checks so we can pop off the end.
lineq = lines[::-1] lineq = lines[::-1]
checkq = checks[::-1] checkq = checks[::-1]
usedlines = [] # We keep the last couple of lines in a deque so we can show context.
usedchecks = [] before = deque(maxlen=self.config.before)
mismatches = []
while lineq and checkq: while lineq and checkq:
line = lineq[-1] line = lineq[-1]
check = checkq[-1] check = checkq[-1]
if check == line: if check.regex.match(line.text):
# This line matched this checker, continue on. # This line matched this checker, continue on.
usedlines.append(line)
usedchecks.append(check)
lineq.pop() lineq.pop()
checkq.pop() checkq.pop()
before.append(line)
elif line.is_empty_space(): elif line.is_empty_space():
# Skip all whitespace input lines. # Skip all whitespace input lines.
lineq.pop() lineq.pop()
else: else:
usedlines.append(line)
usedchecks.append(check)
mismatches.append((line, check))
# Failed to match. # Failed to match.
lineq.pop() lineq.pop()
checkq.pop() line.text = escape_string(line.text.strip()) + "\n"
# Add context, ignoring empty lines.
# Drain empties return TestFailure(
line,
check,
self,
before=[escape_string(line.text.strip()) + "\n" for line in before],
after=[
escape_string(line.text.strip()) + "\n"
for line in lineq[::-1]
if not line.is_empty_space()
],
)
# Drain empties.
while lineq and lineq[-1].is_empty_space(): while lineq and lineq[-1].is_empty_space():
lineq.pop() lineq.pop()
# If there's still lines or checkers, we have a failure.
# Store the remaining lines for the diff
for i in lineq[::-1]:
if not i.is_empty_space():
usedlines.append(i)
# Store remaining checks for the diff
for i in checkq[::-1]:
usedchecks.append(i)
# Do a SequenceMatch! This gives us a diff-like thing.
diff = SequenceMatcher(a=usedlines, b=usedchecks, autojunk=False)
# If there's a mismatch or still lines or checkers, we have a failure.
# Otherwise it's success. # Otherwise it's success.
if mismatches: if lineq:
return TestFailure( return TestFailure(lineq[-1], None, self)
mismatches[0][0],
mismatches[0][1],
self,
diff=diff,
lines=usedlines,
checks=usedchecks,
)
elif lineq:
return TestFailure(
lineq[-1], None, self, diff=diff, lines=usedlines, checks=usedchecks
)
elif checkq: elif checkq:
return TestFailure( return TestFailure(None, checkq[-1], self)
None, checkq[-1], self, diff=diff, lines=usedlines, checks=usedchecks
)
else: else:
# Success!
return None return None
def run(self): def run(self):
""" Run the command. Return a TestFailure, or None. """ """ Run the command. Return a TestFailure, or None. """
def split_by_newlines(s): def split_by_newlines(s):
"""Decode a string and split it by newlines only, """ Decode a string and split it by newlines only,
retaining the newlines. retaining the newlines.
""" """
return [s + "\n" for s in s.decode("utf-8").split("\n")] return [s + "\n" for s in s.decode("utf-8").split("\n")]
PIPE = subprocess.PIPE
if self.config.verbose: if self.config.verbose:
print(self.subbed_command) print(self.subbed_command)
proc = runproc(self.subbed_command) proc = subprocess.Popen(
self.subbed_command,
stdin=PIPE,
stdout=PIPE,
stderr=PIPE,
shell=True,
close_fds=True, # For Python 2.6 as shipped on RHEL 6
)
stdout, stderr = proc.communicate() stdout, stderr = proc.communicate()
# HACK: This is quite cheesy: POSIX specifies that sh should return 127 for a missing command. # HACK: This is quite cheesy: POSIX specifies that sh should return 127 for a missing command.
# It's also possible that it'll be returned in other situations, # Technically it's also possible to return it in other conditions.
# most likely when the last command in a shell script doesn't exist. # Practically, that's *probably* not going to happen.
# So we check if the command *we execute* exists, and complain then.
status = proc.returncode status = proc.returncode
cmd = shlex.split(self.subbed_command)[0] if status == 127:
if status == 127 and not find_command(cmd): raise CheckerError("Command could not be found: " + self.subbed_command)
raise CheckerError("Command could not be found: " + cmd)
if status == 126 and not find_command(cmd):
raise CheckerError("Command is not executable: " + cmd)
outlines = [ outlines = [
Line(text, idx + 1, "stdout") Line(text, idx + 1, "stdout")
@@ -497,10 +351,7 @@ class TestRun(object):
# non-matching or unmatched stderr text, then annotate the outfail # non-matching or unmatched stderr text, then annotate the outfail
# with it. # with it.
if outfail and errfail and errfail.line: if outfail and errfail and errfail.line:
outfail.error_annotation_lines = errlines[errfail.line.number - 1 :] outfail.error_annotation_line = errfail.line
# Trim a trailing newline
if outfail.error_annotation_lines[-1].text == "\n":
del outfail.error_annotation_lines[-1]
return outfail if outfail else errfail return outfail if outfail else errfail
@@ -510,28 +361,6 @@ class CheckCmd(object):
self.type = checktype self.type = checktype
self.regex = regex self.regex = regex
def __hash__(self):
# HACK: We pass this to the Sequencematcher, which puts the Checks into a dict.
# To force it to match the regexes, we return a hash collision intentionally,
# so it falls back on __eq__().
#
# Line has the same thing.
return 0
def __eq__(self, other):
# "Magical" comparison with lines and strings.
# Typically I wouldn't use this, but it allows us to check if a line matches any check in a dict or list via
# the `in` operator.
if other is None:
return False
if isinstance(other, CheckCmd):
return self.regex == other.regex
if isinstance(other, Line):
return self.regex.match(other.text)
if isinstance(other, str):
return self.regex.match(other)
raise NotImplementedError
@staticmethod @staticmethod
def parse(line, checktype): def parse(line, checktype):
# type: (Line) -> CheckCmd # type: (Line) -> CheckCmd
@@ -591,19 +420,14 @@ class Checker(object):
# Find run commands. # Find run commands.
self.runcmds = [RunCmd.parse(sl) for sl in group1s(RUN_RE)] self.runcmds = [RunCmd.parse(sl) for sl in group1s(RUN_RE)]
self.shebang_cmd = None
if not self.runcmds: if not self.runcmds:
# If no RUN command has been given, fall back to the shebang. # If no RUN command has been given, fall back to the shebang.
if lines[0].text.startswith("#!"): if lines[0].text.startswith("#!"):
# Remove the "#!" at the beginning, and the newline at the end. # Remove the "#!" at the beginning, and the newline at the end.
cmd = lines[0].text[2:-1] self.runcmds = [RunCmd(lines[0].text[2:-1] + " %s", lines[0])]
self.shebang_cmd = cmd
self.runcmds = [RunCmd(cmd + " %s", lines[0])]
else: else:
raise CheckerError("No runlines ('# RUN') found") raise CheckerError("No runlines ('# RUN') found")
self.requirecmds = [RunCmd.parse(sl) for sl in group1s(REQUIRES_RE)]
# Find check cmds. # Find check cmds.
self.outchecks = [ self.outchecks = [
CheckCmd.parse(sl, "CHECK") for sl in group1s(CHECK_STDOUT_RE) CheckCmd.parse(sl, "CHECK") for sl in group1s(CHECK_STDOUT_RE)
@@ -618,21 +442,6 @@ def check_file(input_file, name, subs, config, failure_handler):
success = True success = True
lines = Line.readfile(input_file, name) lines = Line.readfile(input_file, name)
checker = Checker(name, lines) checker = Checker(name, lines)
# Run all the REQUIRES lines first,
# if any of them fail it's a SKIP
for reqcmd in checker.requirecmds:
proc = runproc(
perform_substitution(reqcmd.args, subs)
)
proc.communicate()
if proc.returncode > 0:
return SKIP
if checker.shebang_cmd is not None and not find_command(checker.shebang_cmd):
raise CheckerError("Command could not be found: " + checker.shebang_cmd)
# Only then run the RUN lines.
for runcmd in checker.runcmds: for runcmd in checker.runcmds:
failure = TestRun(name, runcmd, checker, subs, config).run() failure = TestRun(name, runcmd, checker, subs, config).run()
if failure: if failure:
@@ -647,8 +456,8 @@ def check_path(path, subs, config, failure_handler):
def parse_subs(subs): def parse_subs(subs):
"""Given a list of input substitutions like 'foo=bar', """ Given a list of input substitutions like 'foo=bar',
return a dictionary like {foo:bar}, or exit if invalid. return a dictionary like {foo:bar}, or exit if invalid.
""" """
result = {} result = {}
for sub in subs: for sub in subs:
@@ -688,14 +497,23 @@ def get_argparse():
help="Show the files to be checked", help="Show the files to be checked",
default=False, default=False,
) )
parser.add_argument(
"--force-color",
action="store_true",
dest="force_color",
help="Force usage of color even if not connected to a terminal",
default=False,
)
parser.add_argument("file", nargs="+", help="File to check") parser.add_argument("file", nargs="+", help="File to check")
parser.add_argument(
"-A",
"--after",
type=int,
help="How many non-empty lines of output after a failure to print (default: 5)",
action="store",
default=5,
)
parser.add_argument(
"-B",
"--before",
type=int,
help="How many non-empty lines of output before a failure to print (default: 5)",
action="store",
default=5,
)
return parser return parser
@@ -705,16 +523,19 @@ def main():
def_subs = {"%": "%"} def_subs = {"%": "%"}
def_subs.update(parse_subs(args.substitute)) def_subs.update(parse_subs(args.substitute))
tests_count = 0 failure_count = 0
failed = False
skip_count = 0
config = Config() config = Config()
config.colorize = args.force_color or sys.stdout.isatty() config.colorize = sys.stdout.isatty()
config.progress = args.progress config.progress = args.progress
fields = config.colors() fields = config.colors()
config.after = args.after
config.before = args.before
if config.before < 0:
raise ValueError("Before must be at least 0")
if config.after < 0:
raise ValueError("After must be at least 0")
for path in args.file: for path in args.file:
tests_count += 1
fields["path"] = path fields["path"] = path
if config.progress: if config.progress:
print("Testing file {path} ... ".format(**fields), end="") print("Testing file {path} ... ".format(**fields), end="")
@@ -722,32 +543,17 @@ def main():
subs = def_subs.copy() subs = def_subs.copy()
subs["s"] = path subs["s"] = path
starttime = datetime.datetime.now() starttime = datetime.datetime.now()
ret = check_path(path, subs, config, TestFailure.print_message) if not check_path(path, subs, config, TestFailure.print_message):
if not ret: failure_count += 1
failed = True
elif config.progress: elif config.progress:
endtime = datetime.datetime.now() endtime = datetime.datetime.now()
duration_ms = round((endtime - starttime).total_seconds() * 1000) duration_ms = round((endtime - starttime).total_seconds() * 1000)
reason = "ok"
color = "{GREEN}"
if ret is SKIP:
skip_count += 1
reason = "SKIPPED"
color = "{BLUE}"
print( print(
(color + "{reason}{RESET} ({duration} ms)").format( "{GREEN}ok{RESET} ({duration} ms)".format(
duration=duration_ms, reason=reason, **fields duration=duration_ms, **fields
) )
) )
sys.exit(failure_count)
# To facilitate integration with testing frameworks, use exit code 125 to indicate that all
# tests have been skipped (primarily for use when tests are run one at a time). Exit code 125 is
# used to indicate to automated `git bisect` runs that a revision has been skipped; we use it
# for the same reasons git does.
if skip_count > 0 and skip_count == tests_count:
sys.exit(125)
sys.exit(1 if failed else 0)
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -47,10 +47,6 @@ NOTARIZE_UUID=$(xcrun altool --notarize-app \
test -z "$NOTARIZE_UUID" && cat "$LOGFILE" && die "Could not get RequestUUID" test -z "$NOTARIZE_UUID" && cat "$LOGFILE" && die "Could not get RequestUUID"
echo "RequestUUID: $NOTARIZE_UUID" echo "RequestUUID: $NOTARIZE_UUID"
# notarization-info doesn't always know about our request immediately.
echo "Giving notarization-info a chance to catch up..."
sleep 15
success=0 success=0
for i in $(seq 20); do for i in $(seq 20); do
echo "Checking progress..." echo "Checking progress..."

View File

@@ -17,9 +17,10 @@ set -x
#Exit on error #Exit on error
set -e set -e
# Respect MAC_CODESIGN_ID, or default for ad-hoc. # Respect MAC_CODESIGN_ID and MAC_PRODUCTSIGN_ID, or default for ad-hoc.
# Note the :- means "or default" and the following - is the value. # Note the :- means "or default" and the following - is the value.
MAC_CODESIGN_ID=${MAC_CODESIGN_ID:--} MAC_CODESIGN_ID=${MAC_CODESIGN_ID:--}
MAC_PRODUCTSIGN_ID=${MAC_PRODUCTSIGN_ID:--}
PKGDIR=$(mktemp -d) PKGDIR=$(mktemp -d)
@@ -27,14 +28,12 @@ SRC_DIR=$PWD
OUTPUT_PATH=${FISH_ARTEFACT_PATH:-~/fish_built} OUTPUT_PATH=${FISH_ARTEFACT_PATH:-~/fish_built}
mkdir -p "$PKGDIR/build" "$PKGDIR/root" "$PKGDIR/intermediates" "$PKGDIR/dst" mkdir -p "$PKGDIR/build" "$PKGDIR/root" "$PKGDIR/intermediates" "$PKGDIR/dst"
{ cd "$PKGDIR/build" && cmake -DMAC_INJECT_GET_TASK_ALLOW=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo -DWITH_GETTEXT=OFF -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' -DMAC_CODESIGN_ID="${MAC_CODESIGN_ID}" "$SRC_DIR" && make VERBOSE=1 -j 12 && env DESTDIR="$PKGDIR/root/" make install; } { cd "$PKGDIR/build" && cmake -DMAC_INJECT_GET_TASK_ALLOW=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo -DMAC_CODESIGN_ID="${MAC_CODESIGN_ID}" "$SRC_DIR" && make -j 12 && env DESTDIR="$PKGDIR/root/" make install; }
pkgbuild --scripts "$SRC_DIR/build_tools/osx_package_scripts" --root "$PKGDIR/root/" --identifier 'com.ridiculousfish.fish-shell-pkg' --version "$VERSION" "$PKGDIR/intermediates/fish.pkg" pkgbuild --scripts "$SRC_DIR/build_tools/osx_package_scripts" --root "$PKGDIR/root/" --identifier 'com.ridiculousfish.fish-shell-pkg' --version "$VERSION" "$PKGDIR/intermediates/fish.pkg"
productbuild --package-path "$PKGDIR/intermediates" --distribution "$SRC_DIR/build_tools/osx_distribution.xml" --resources "$SRC_DIR/build_tools/osx_package_resources/" "$OUTPUT_PATH/fish-$VERSION.pkg" productbuild --package-path "$PKGDIR/intermediates" --distribution "$SRC_DIR/build_tools/osx_distribution.xml" --resources "$SRC_DIR/build_tools/osx_package_resources/" "$OUTPUT_PATH/fish-$VERSION.pkg"
MAC_PRODUCTSIGN_ID=${MAC_PRODUCTSIGN_ID:--}
productsign --sign "${MAC_PRODUCTSIGN_ID}" "$OUTPUT_PATH/fish-$VERSION.pkg" "$OUTPUT_PATH/fish-$VERSION-signed.pkg" && mv "$OUTPUT_PATH/fish-$VERSION-signed.pkg" "$OUTPUT_PATH/fish-$VERSION.pkg" productsign --sign "${MAC_PRODUCTSIGN_ID}" "$OUTPUT_PATH/fish-$VERSION.pkg" "$OUTPUT_PATH/fish-$VERSION-signed.pkg" && mv "$OUTPUT_PATH/fish-$VERSION-signed.pkg" "$OUTPUT_PATH/fish-$VERSION.pkg"
# Make the app # Make the app
{ cd "$PKGDIR/build" && make -j 12 signed_fish_macapp && zip -r "$OUTPUT_PATH/fish-$VERSION.app.zip" fish.app; } { cd "$PKGDIR/build" && make signed_fish_macapp && zip -r "$OUTPUT_PATH/fish-$VERSION.app.zip" fish.app; }
rm -r "$PKGDIR" rm -r "$PKGDIR"

View File

@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?> <?xml version="1.0" encoding="utf-8" standalone="no"?>
<installer-gui-script minSpecVersion="1"> <installer-gui-script minSpecVersion="1">
<title>fish shell</title> <title>fish shell</title>
<welcome file="welcome.html" mime-type="text/html"/> <welcome file="welcome.rtf"/>
<background file="terminal_logo.png" scaling="proportional" alignment="bottomleft"/> <background file="terminal_logo.png" scaling="proportional" alignment="bottomleft"/>
<pkg-ref id="com.ridiculousfish.fish-shell-pkg"/> <pkg-ref id="com.ridiculousfish.fish-shell-pkg"/>
<options hostArchitectures="arm64,x86_64" rootVolumeOnly="true"/> <options customize="never" require-scripts="false"/>
<options customize="never" require-scripts="true"/>
<choices-outline> <choices-outline>
<line choice="default"> <line choice="default">
<line choice="com.ridiculousfish.fish-shell-pkg"/> <line choice="com.ridiculousfish.fish-shell-pkg"/>

View File

@@ -1,29 +0,0 @@
<html>
<head>
<style>
body {
font-family: system-ui, -apple-system, "Helvetica Neue", sans-serif;
font-size: 10pt;
}
code, tt {
font-family: ui-monospace, Menlo, monospace;
}
</style>
</head>
<body>
<p>
<strong>fish</strong> is a smart and user-friendly command line shell. For more information, visit <a href="https://fishshell.com">fishshell.com</a>.
</p>
<p>
<strong>fish</strong> will be installed into <tt>/usr/local/</tt>, and its path will be added to <wbr><tt>/etc/shells</tt> if necessary.
</p>
<p>
Your default shell will <em>not</em> be changed. To make <strong>fish</strong> your login shell after the installation, run:
</p>
<p>
<code>chsh -s /usr/local/bin/fish</code>
</p>
<p>Enjoy! Bugs can be reported on <a href="https://github.org/fish-shell/fish-shell/">GitHub</a>.</p>
</body>
</html>

View File

@@ -0,0 +1,26 @@
{\rtf1\ansi\ansicpg1252\cocoartf1485\cocoasubrtf410
{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;\f1\fnil\fcharset0 Menlo-Regular;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;\csgenericrgb\c100000\c100000\c100000;}
{\info
{\author dlkfjslfjsfdlkfk}}\margl1440\margr1440\vieww10800\viewh8400\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
\f0\fs30 \cf0 Fish is a smart and user friendly command line shell. For more information, visit {\field{\*\fldinst{HYPERLINK "https://fishshell.com"}}{\fldrslt https://fishshell.com}}\
\
fish will be installed into
\f1\fs26 /usr/local/
\f0\fs30 , and fish will be added to
\f1\fs26 /etc/shells
\f0\fs30 if necessary.\
\
Your default shell will
\i not
\i0 be changed. To make fish your default, run:\
\
\f1 chsh -s /usr/local/bin/fish
\f0 \
\
Enjoy!\
}

View File

@@ -1,3 +1,3 @@
#!/bin/sh -x #!/bin/sh -x
./add-shell ${DSTVOLUME}usr/local/bin/fish ./add-shell /usr/local/bin/fish > /tmp/fish_postinstall_output.log

View File

@@ -1,7 +0,0 @@
#!/bin/sh -x
echo "Removing any previous installation"
pkgutil --pkg-info ${INSTALL_PKG_SESSION_ID} && pkgutil --only-files --files ${INSTALL_PKG_SESSION_ID} | while read installed
do rm -v ${DSTVOLUME}${installed}
done
echo "... removed"

View File

@@ -26,26 +26,20 @@ import pexpect
# Default timeout for failing to match. # Default timeout for failing to match.
TIMEOUT_SECS = 5 TIMEOUT_SECS = 5
UNEXPECTED_SUCCESS = object()
def get_prompt_re(counter): def get_prompt_re(counter):
"""Return a regular expression for matching a with a given prompt counter.""" """ Return a regular expression for matching a with a given prompt counter. """
return re.compile( return re.compile(
r"""(?:\r\n?|^) # beginning of line r"""(?:\r\n?|^) # beginning of line
(?:\x1b[\d\[KB(m]*)* # optional colors
(?:\[.\]\ )? # optional vi mode prompt (?:\[.\]\ )? # optional vi mode prompt
""" """
+ (r"prompt\ %d>" % counter) # prompt with counter + (r"prompt\ %d>" % counter), # prompt with counter
+ r"""
(?:\x1b[\d\[KB(m]*)* # optional colors
""",
re.VERBOSE, re.VERBOSE,
) )
def get_callsite(): def get_callsite():
"""Return a triple (filename, line_number, line_text) of the call site location.""" """ Return a triple (filename, line_number, line_text) of the call site location. """
callstack = inspect.getouterframes(inspect.currentframe()) callstack = inspect.getouterframes(inspect.currentframe())
for f in callstack: for f in callstack:
if inspect.getmodule(f.frame) is not Message.MODULE: if inspect.getmodule(f.frame) is not Message.MODULE:
@@ -54,7 +48,7 @@ def get_callsite():
def escape(s): def escape(s):
"""Escape the string 's' to make it human-understandable.""" """ Escape the string 's' to make it human-understandable. """
res = [] res = []
for c in s: for c in s:
if c == "\n": if c == "\n":
@@ -71,19 +65,17 @@ def escape(s):
def pexpect_error_type(err): def pexpect_error_type(err):
"""Return a human-readable description of a pexpect error type.""" """ Return a human-readable description of a pexpect error type. """
if isinstance(err, pexpect.EOF): if isinstance(err, pexpect.EOF):
return "EOF" return "EOF"
elif isinstance(err, pexpect.TIMEOUT): elif isinstance(err, pexpect.TIMEOUT):
return "timeout" return "timeout"
elif err is UNEXPECTED_SUCCESS:
return "unexpected success"
else: else:
return "unknown error" return "unknown error"
class Message(object): class Message(object):
"""Some text either sent-to or received-from the spawned proc. """ Some text either sent-to or received-from the spawned proc.
Attributes: Attributes:
dir: the message direction, either DIR_INPUT or DIR_OUTPUT dir: the message direction, either DIR_INPUT or DIR_OUTPUT
@@ -101,7 +93,7 @@ class Message(object):
MODULE = sys.modules[__name__] MODULE = sys.modules[__name__]
def __init__(self, dir, text, when): def __init__(self, dir, text, when):
"""Construct from a direction, message text and timestamp.""" """ Construct from a direction, message text and timestamp. """
self.dir = dir self.dir = dir
self.filename, self.lineno, _ = get_callsite() self.filename, self.lineno, _ = get_callsite()
self.text = text self.text = text
@@ -109,17 +101,17 @@ class Message(object):
@staticmethod @staticmethod
def sent_input(text, when): def sent_input(text, when):
"""Return an input message with the given text.""" """ Return an input message with the given text. """
return Message(Message.DIR_INPUT, text, when) return Message(Message.DIR_INPUT, text, when)
@staticmethod @staticmethod
def received_output(text, when): def received_output(text, when):
"""Return a output message with the given text.""" """ Return a output message with the given text. """
return Message(Message.DIR_OUTPUT, text, when) return Message(Message.DIR_OUTPUT, text, when)
class SpawnedProc(object): class SpawnedProc(object):
"""A process, talking to our ptty. This wraps pexpect.spawn. """ A process, talking to our ptty. This wraps pexpect.spawn.
Attributes: Attributes:
colorize: whether error messages should have ANSI color escapes colorize: whether error messages should have ANSI color escapes
@@ -130,41 +122,37 @@ class SpawnedProc(object):
function to ensure that each printed prompt is distinct. function to ensure that each printed prompt is distinct.
""" """
def __init__( def __init__(self, name="fish", timeout=TIMEOUT_SECS, env=os.environ.copy()):
self, name="fish", timeout=TIMEOUT_SECS, env=os.environ.copy(), **kwargs """ Construct from a name, timeout, and environment.
):
"""Construct from a name, timeout, and environment.
Args: Args:
name: the name of the executable to launch, as a key into the name: the name of the executable to launch, as a key into the
environment dictionary. By default this is 'fish' but may be environment dictionary. By default this is 'fish' but may be
other executables. other executables.
timeout: A timeout to pass to pexpect. This indicates how long to wait timeout: A timeout to pass to pexpect. This indicates how long to wait
before giving up on some expected output. before giving up on some expected output.
env: a string->string dictionary, describing the environment variables. env: a string->string dictionary, describing the environment variables.
""" """
if name not in env: if name not in env:
raise ValueError("'%s' variable not found in environment" % name) raise ValueError("'name' variable not found in environment" % name)
exe_path = env.get(name) exe_path = env.get(name)
self.colorize = sys.stdout.isatty() or env.get("FISH_FORCE_COLOR", "0") == "1" self.colorize = sys.stdout.isatty()
self.messages = [] self.messages = []
self.start_time = None self.start_time = None
self.spawn = pexpect.spawn( self.spawn = pexpect.spawn(exe_path, env=env, encoding="utf-8", timeout=timeout)
exe_path, env=env, encoding="utf-8", timeout=timeout, **kwargs
)
self.spawn.delaybeforesend = None self.spawn.delaybeforesend = None
self.prompt_counter = 0 self.prompt_counter = 1
def time_since_first_message(self): def time_since_first_message(self):
"""Return a delta in seconds since the first message, or 0 if this is the first.""" """ Return a delta in seconds since the first message, or 0 if this is the first. """
now = time.monotonic() now = time.monotonic()
if not self.start_time: if not self.start_time:
self.start_time = now self.start_time = now
return now - self.start_time return now - self.start_time
def send(self, s): def send(self, s):
"""Cover over pexpect.spawn.send(). """ Cover over pexpect.spawn.send().
Send the given string to the tty, returning the number of bytes written. Send the given string to the tty, returning the number of bytes written.
""" """
res = self.spawn.send(s) res = self.spawn.send(s)
when = self.time_since_first_message() when = self.time_since_first_message()
@@ -172,74 +160,61 @@ class SpawnedProc(object):
return res return res
def sendline(self, s): def sendline(self, s):
"""Cover over pexpect.spawn.sendline(). """ Cover over pexpect.spawn.sendline().
Send the given string + linesep to the tty, returning the number of bytes written. Send the given string + linesep to the tty, returning the number of bytes written.
""" """
return self.send(s + os.linesep) return self.send(s + os.linesep)
def expect_re(self, pat, pat_desc=None, unmatched=None, shouldfail=False, **kwargs): def expect_re(self, pat, pat_desc=None, unmatched=None, **kwargs):
"""Cover over pexpect.spawn.expect(). """ Cover over pexpect.spawn.expect().
Consume all "new" output of self.spawn until the given pattern is matched, or Consume all "new" output of self.spawn until the given pattern is matched, or
the timeout is reached. the timeout is reached.
Note that output between the current position and the location of the match is Note that output between the current position and the location of the match is
consumed as well. consumed as well.
The pattern is typically a regular expression in string form, but may also be The pattern is typically a regular expression in string form, but may also be
any of the types accepted by pexpect.spawn.expect(). any of the types accepted by pexpect.spawn.expect().
If the 'unmatched' parameter is given, it is printed as part of the error message If the 'unmatched' parameter is given, it is printed as part of the error message
of any failure. of any failure.
On failure, this prints an error and exits. On failure, this prints an error and exits.
""" """
try: try:
self.spawn.expect(pat, **kwargs) res = self.spawn.expect(pat, **kwargs)
when = self.time_since_first_message() when = self.time_since_first_message()
self.messages.append( self.messages.append(
Message.received_output(self.spawn.match.group(), when) Message.received_output(self.spawn.match.group(), when)
) )
# When a match is found, return res
# spawn.match is the MatchObject that produced it.
# This can be used to check what exactly was matched.
if shouldfail:
err = UNEXPECTED_SUCCESS
if not pat_desc:
pat_desc = str(pat)
self.report_exception_and_exit(pat_desc, unmatched, err)
return self.spawn.match
except pexpect.ExceptionPexpect as err: except pexpect.ExceptionPexpect as err:
if shouldfail:
return True
if not pat_desc: if not pat_desc:
pat_desc = str(pat) pat_desc = str(pat)
self.report_exception_and_exit(pat_desc, unmatched, err) self.report_exception_and_exit(pat_desc, unmatched, err)
def expect_str(self, s, **kwargs): def expect_str(self, s, **kwargs):
"""Cover over expect_re() which accepts a literal string.""" """ Cover over expect_re() which accepts a literal string. """
return self.expect_re(re.escape(s), **kwargs) return self.expect_re(re.escape(s), **kwargs)
def expect_prompt(self, *args, increment=True, **kwargs): def expect_prompt(self, *args, **kwargs):
"""Convenience function which matches some text and then a prompt. """ Convenience function which matches some text and then a prompt.
Match the given positional arguments as expect_re, and then look Match the given positional arguments as expect_re, and then look
for a prompt. for a prompt, bumping the prompt counter.
If increment is set, then this should be a new prompt and the prompt counter Returns None on success, and exits on failure.
should be bumped; otherwise this is not a new prompt. Example:
Returns None on success, and exits on failure. sp.sendline("echo hello world")
Example: sp.expect_prompt("hello world")
sp.sendline("echo hello world")
sp.expect_prompt("hello world")
""" """
if args: if args:
self.expect_re(*args, **kwargs) self.expect_re(*args, **kwargs)
if increment:
self.prompt_counter += 1
self.expect_re( self.expect_re(
get_prompt_re(self.prompt_counter), get_prompt_re(self.prompt_counter),
pat_desc="prompt %d" % self.prompt_counter, pat_desc="prompt %d" % self.prompt_counter,
) )
self.prompt_counter += 1
def report_exception_and_exit(self, pat, unmatched, err): def report_exception_and_exit(self, pat, unmatched, err):
"""Things have gone badly. """ Things have gone badly.
We have an exception 'err', some pexpect.ExceptionPexpect. We have an exception 'err', some pexpect.ExceptionPexpect.
Report it to stdout, along with the offending call site. Report it to stdout, along with the offending call site.
If 'unmatched' is set, print it to stdout. If 'unmatched' is set, print it to stdout.
""" """
colors = self.colors() colors = self.colors()
failtype = pexpect_error_type(err) failtype = pexpect_error_type(err)
@@ -268,18 +243,23 @@ class SpawnedProc(object):
print("{CYAN}Escaped buffer:{RESET}".format(**colors)) print("{CYAN}Escaped buffer:{RESET}".format(**colors))
print(escape(self.spawn.before)) print(escape(self.spawn.before))
print("") print("")
print("{CYAN}When written to the tty, this looks like:{RESET}".format(**colors)) if sys.stdout.isatty():
print("{CYAN}<-------{RESET}".format(**colors)) print(
sys.stdout.write(self.spawn.before) "{CYAN}When written to the tty, this looks like:{RESET}".format(
sys.stdout.flush() **colors
print("{RESET}\n{CYAN}------->{RESET}".format(**colors)) )
)
print("{CYAN}<-------{RESET}".format(**colors))
sys.stdout.write(self.spawn.before)
sys.stdout.flush()
print("{RESET}\n{CYAN}------->{RESET}".format(**colors))
print("") print("")
# Show the last 10 messages. # Show the last 5 messages.
print("Last 10 messages:") print("Last 5 messages:")
delta = None delta = None
for m in self.messages[-10:]: for m in self.messages[-5:]:
etext = escape(m.text) etext = escape(m.text)
timestamp = m.when * 1000.0 timestamp = m.when * 1000.0
# Use relative timestamps and add a sign. # Use relative timestamps and add a sign.
@@ -291,6 +271,7 @@ class SpawnedProc(object):
else: else:
timestampstr = "{timestamp:10.2f} ms".format(timestamp=timestamp) timestampstr = "{timestamp:10.2f} ms".format(timestamp=timestamp)
delta = m.when * 1000.0 delta = m.when * 1000.0
dir = m.dir
print( print(
"{dir} {timestampstr} (Line {lineno}): {BOLD}{etext}{RESET}".format( "{dir} {timestampstr} (Line {lineno}): {BOLD}{etext}{RESET}".format(
dir=m.dir, dir=m.dir,
@@ -305,14 +286,14 @@ class SpawnedProc(object):
sys.exit(1) sys.exit(1)
def sleep(self, secs): def sleep(self, secs):
"""Cover over time.sleep().""" """ Cover over time.sleep(). """
time.sleep(secs) time.sleep(secs)
def colors(self): def colors(self):
"""Return a dictionary mapping color names to ANSI escapes""" """ Return a dictionary mapping color names to ANSI escapes """
def ansic(n): def ansic(n):
"""Return either an ANSI escape sequence for a color, or empty string.""" """ Return either an ANSI escape sequence for a color, or empty string. """
return "\033[%dm" % n if self.colorize else "" return "\033[%dm" % n if self.colorize else ""
return { return {

View File

@@ -28,8 +28,8 @@ if test $all = yes
exit 1 exit 1
end end
set c_files src/*.h src/*.cpp src/*.c set c_files src/*.h src/*.cpp src/*.c
set fish_files share/**.fish set fish_files (printf '%s\n' share/***.fish)
set python_files {doc_src,share,tests}/**.py set python_files **.py
else else
# We haven't been asked to reformat all the source. If there are uncommitted changes reformat # We haven't been asked to reformat all the source. If there are uncommitted changes reformat
# those using `git clang-format`. Else reformat the files in the most recent commit. # those using `git clang-format`. Else reformat the files in the most recent commit.

View File

@@ -0,0 +1,3 @@
# Ubuntu Xenial (used for Travis CI builds) ships libstdc++ 5.4.0 which contains undefined behaviour
# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63345
object-size:*bits/stl_tree.h

View File

@@ -56,9 +56,9 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
endif() endif()
if(_lang STREQUAL "C") if(_lang STREQUAL "C")
set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckIncludeFiles/${VARIABLE}.c) set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckIncludeFiles/${var}.c)
elseif(_lang STREQUAL "CXX") elseif(_lang STREQUAL "CXX")
set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckIncludeFiles/${VARIABLE}.cpp) set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckIncludeFiles/${var}.cpp)
else() else()
message(FATAL_ERROR "Unknown language:\n ${_lang}\nSupported languages: C, CXX.\n") message(FATAL_ERROR "Unknown language:\n ${_lang}\nSupported languages: C, CXX.\n")
endif() endif()

View File

@@ -4,33 +4,15 @@
# `wcstod_l` is a GNU-extension, sometimes hidden behind GNU-related defines. # `wcstod_l` is a GNU-extension, sometimes hidden behind GNU-related defines.
# This is the case for at least Cygwin and Newlib. # This is the case for at least Cygwin and Newlib.
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE=1) list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE=1)
include(CheckCXXCompilerFlag)
if(APPLE) if(APPLE)
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-Werror=unguarded-availability" REQUIRES_UNGUARDED_AVAILABILITY) check_cxx_compiler_flag("-Werror=unguarded-availability" REQUIRES_UNGUARDED_AVAILABILITY)
if(REQUIRES_UNGUARDED_AVAILABILITY) if(REQUIRES_UNGUARDED_AVAILABILITY)
list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "-Werror=unguarded-availability") list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "-Werror=unguarded-availability")
endif() endif()
endif() endif()
# An unrecognized flag is usually a warning and not an error, which CMake apparently does
# not pick up on. Combine it with -Werror to determine if it's actually supported.
# This is not bulletproof; old versions of GCC only emit a warning about unrecognized warning
# options when there are other warnings to emit :rolleyes:
# See https://github.com/fish-shell/fish-shell/commit/fe2da0a9#commitcomment-47431659
# GCC supports -Wno-redundant-move from GCC9 onwards
check_cxx_compiler_flag("-Werror=no-redundant-move" HAS_NO_REDUNDANT_MOVE)
if (HAS_NO_REDUNDANT_MOVE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-redundant-move")
endif()
# Clang once supported -Wno-redundant-move but replaced it with a Wredundant-move option instead
# (and it is functionally different from its older version of GCC's Wno-redundant-move).
check_cxx_compiler_flag("-Werror=redundant-move" HAS_REDUNDANT_MOVE)
if (HAS_REDUNDANT_MOVE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wredundant-move")
endif()
# Try using CMake's own logic to locate curses/ncurses # Try using CMake's own logic to locate curses/ncurses
find_package(Curses) find_package(Curses)
if(NOT ${CURSES_FOUND}) if(NOT ${CURSES_FOUND})
@@ -43,19 +25,13 @@ if(NOT ${CURSES_FOUND})
set(CURSES_CURSES_LIBRARY ${CURSES_LIBRARIES}) set(CURSES_CURSES_LIBRARY ${CURSES_LIBRARIES})
set(CURSES_LIBRARY ${CURSES_LIBRARIES}) set(CURSES_LIBRARY ${CURSES_LIBRARIES})
endif() endif()
# Set up extra include directories for CheckIncludeFile
list(APPEND CMAKE_REQUIRED_INCLUDES ${CURSES_INCLUDE_DIRS})
# Fix undefined reference to tparm on RHEL 6 and potentially others
# If curses is found via CMake, it also links against tinfo if it exists. But if we use our
# fallback pkg-config logic above, we need to do this manually.
find_library(CURSES_TINFO tinfo)
if (CURSES_TINFO)
set(CURSES_LIBRARY ${CURSES_LIBRARY} ${CURSES_TINFO})
endif()
# Get threads. # Get threads.
set(THREADS_PREFER_PTHREAD_FLAG ON) set(THREADS_PREFER_PTHREAD_FLAG ON)
# FindThreads < 3.4.0 doesn't work for C++-only projects
if(CMAKE_VERSION VERSION_LESS 3.4.0)
enable_language(C)
endif()
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
# Detect WSL. Does not match against native Windows/WIN32. # Detect WSL. Does not match against native Windows/WIN32.
@@ -74,26 +50,22 @@ include(CheckCXXSourceCompiles)
include(CheckTypeSize) include(CheckTypeSize)
include(CMakePushCheckState) include(CMakePushCheckState)
check_cxx_symbol_exists(backtrace_symbols execinfo.h HAVE_BACKTRACE_SYMBOLS) check_cxx_symbol_exists(backtrace_symbols execinfo.h HAVE_BACKTRACE_SYMBOLS)
check_cxx_symbol_exists(clock_gettime time.h HAVE_CLOCK_GETTIME)
# workaround for lousy mtime precision on a Linux kernel
if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
check_cxx_symbol_exists(clock_gettime time.h HAVE_CLOCK_GETTIME)
check_cxx_symbol_exists(futimens sys/stat.h HAVE_FUTIMENS)
if ((HAVE_CLOCK_GETTIME) AND (HAVE_FUTIMENS))
set(UVAR_FILE_SET_MTIME_HACK 1)
endif()
endif()
check_cxx_symbol_exists(ctermid_r stdio.h HAVE_CTERMID_R) check_cxx_symbol_exists(ctermid_r stdio.h HAVE_CTERMID_R)
check_struct_has_member("struct dirent" d_type dirent.h HAVE_STRUCT_DIRENT_D_TYPE LANGUAGE CXX) check_struct_has_member("struct dirent" d_type dirent.h HAVE_STRUCT_DIRENT_D_TYPE LANGUAGE CXX)
check_cxx_symbol_exists(dirfd "sys/types.h;dirent.h" HAVE_DIRFD) check_cxx_symbol_exists(dirfd "sys/types.h;dirent.h" HAVE_DIRFD)
check_include_file_cxx(execinfo.h HAVE_EXECINFO_H) check_include_file_cxx(execinfo.h HAVE_EXECINFO_H)
check_cxx_symbol_exists(flock sys/file.h HAVE_FLOCK) check_cxx_symbol_exists(flock sys/file.h HAVE_FLOCK)
# futimens is new in OS X 10.13 but is a weak symbol.
# Don't assume it exists just because we can link - it may be null.
check_cxx_symbol_exists(futimens sys/stat.h HAVE_FUTIMENS)
check_cxx_symbol_exists(futimes sys/time.h HAVE_FUTIMES)
check_cxx_symbol_exists(getifaddrs ifaddrs.h HAVE_GETIFADDRS) check_cxx_symbol_exists(getifaddrs ifaddrs.h HAVE_GETIFADDRS)
check_cxx_symbol_exists(getpwent pwd.h HAVE_GETPWENT) check_cxx_symbol_exists(getpwent pwd.h HAVE_GETPWENT)
check_cxx_symbol_exists(getrusage sys/resource.h HAVE_GETRUSAGE) check_cxx_symbol_exists(getrusage sys/resource.h HAVE_GETRUSAGE)
check_cxx_symbol_exists(gettext libintl.h HAVE_GETTEXT) check_cxx_symbol_exists(gettext libintl.h HAVE_GETTEXT)
check_cxx_symbol_exists(killpg "sys/types.h;signal.h" HAVE_KILLPG) check_cxx_symbol_exists(killpg "sys/types.h;signal.h" HAVE_KILLPG)
check_cxx_symbol_exists(lrand48_r stdlib.h HAVE_LRAND48_R)
# mkostemp is in stdlib in glibc and FreeBSD, but unistd on macOS # mkostemp is in stdlib in glibc and FreeBSD, but unistd on macOS
check_cxx_symbol_exists(mkostemp "stdlib.h;unistd.h" HAVE_MKOSTEMP) check_cxx_symbol_exists(mkostemp "stdlib.h;unistd.h" HAVE_MKOSTEMP)
set(HAVE_CURSES_H ${CURSES_HAVE_CURSES_H}) set(HAVE_CURSES_H ${CURSES_HAVE_CURSES_H})
@@ -113,19 +85,12 @@ check_struct_has_member("struct stat" st_mtimespec.tv_nsec "sys/stat.h"
HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC LANGUAGE CXX) HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC LANGUAGE CXX)
check_struct_has_member("struct stat" st_mtim.tv_nsec "sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC check_struct_has_member("struct stat" st_mtim.tv_nsec "sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
LANGUAGE CXX) LANGUAGE CXX)
check_cxx_symbol_exists(sys_errlist stdio.h HAVE_SYS_ERRLIST)
check_include_file_cxx(sys/ioctl.h HAVE_SYS_IOCTL_H) check_include_file_cxx(sys/ioctl.h HAVE_SYS_IOCTL_H)
check_include_file_cxx(sys/select.h HAVE_SYS_SELECT_H) check_include_file_cxx(sys/select.h HAVE_SYS_SELECT_H)
# glibc 2.30 deprecated <sys/sysctl.h> because that's what glibc does.
# Checking for that here rather than hardcoding a check on the glibc
# version in the C++ sources at point of use makes more sense.
SET(OLD_CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
check_include_files("sys/types.h;sys/sysctl.h" HAVE_SYS_SYSCTL_H) check_include_files("sys/types.h;sys/sysctl.h" HAVE_SYS_SYSCTL_H)
SET(CMAKE_C_FLAGS "${OLD_CMAKE_C_FLAGS}") check_include_file_cxx(termios.h HAVE_TERMIOS_H) # Needed for TIOCGWINSZ
check_cxx_symbol_exists(eventfd sys/eventfd.h HAVE_EVENTFD)
check_cxx_symbol_exists(pipe2 unistd.h HAVE_PIPE2)
check_cxx_symbol_exists(wcscasecmp wchar.h HAVE_WCSCASECMP) check_cxx_symbol_exists(wcscasecmp wchar.h HAVE_WCSCASECMP)
check_cxx_symbol_exists(wcsdup wchar.h HAVE_WCSDUP) check_cxx_symbol_exists(wcsdup wchar.h HAVE_WCSDUP)
check_cxx_symbol_exists(wcslcpy wchar.h HAVE_WCSLCPY) check_cxx_symbol_exists(wcslcpy wchar.h HAVE_WCSLCPY)
@@ -153,7 +118,7 @@ endif()
list(APPEND WCSTOD_L_INCLUDES "wchar.h") list(APPEND WCSTOD_L_INCLUDES "wchar.h")
check_cxx_symbol_exists(wcstod_l "${WCSTOD_L_INCLUDES}" HAVE_WCSTOD_L) check_cxx_symbol_exists(wcstod_l "${WCSTOD_L_INCLUDES}" HAVE_WCSTOD_L)
check_cxx_symbol_exists(uselocale "locale.h;xlocale.h" HAVE_USELOCALE) check_cxx_symbol_exists(_sys_errs stdlib.h HAVE__SYS__ERRS)
cmake_push_check_state() cmake_push_check_state()
set(CMAKE_EXTRA_INCLUDE_FILES termios.h sys/ioctl.h) set(CMAKE_EXTRA_INCLUDE_FILES termios.h sys/ioctl.h)
@@ -181,9 +146,9 @@ elseif(HAVE_NCURSES_TERM_H)
set(TPARM_INCLUDES "${TPARM_INCLUDES}#include <ncurses/term.h>\n") set(TPARM_INCLUDES "${TPARM_INCLUDES}#include <ncurses/term.h>\n")
endif() endif()
# Solaris and X/Open-conforming systems have a fixed-args tparm
cmake_push_check_state() cmake_push_check_state()
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CURSES_LIBRARY}) list(APPEND CMAKE_REQUIRED_LIBRARIES ${CURSES_LIBRARY})
# Solaris and X/Open-conforming systems have a fixed-args tparm
check_cxx_source_compiles(" check_cxx_source_compiles("
#define TPARM_VARARGS #define TPARM_VARARGS
${TPARM_INCLUDES} ${TPARM_INCLUDES}
@@ -195,23 +160,6 @@ int main () {
TPARM_TAKES_VARARGS TPARM_TAKES_VARARGS
) )
# Check if tputs needs a function reading an int or char.
# The only curses I can find that needs a char is OpenIndiana.
check_cxx_source_compiles("
#include <curses.h>
#include <term.h>
static int writer(int b) {
return b;
}
int main() {
return tputs(\"foo\", 5, writer);
}"
TPUTS_USES_INT_ARG
)
if(TPARM_TAKES_VARARGS) if(TPARM_TAKES_VARARGS)
set(TPARM_VARARGS 1) set(TPARM_VARARGS 1)
else() else()
@@ -251,23 +199,11 @@ int main () {
check_cxx_source_compiles(" check_cxx_source_compiles("
#include <atomic> #include <atomic>
#include <cstdint> #include <cstdint>
std::atomic<uint64_t> x (0); std::atomic<uint64_t> x;
int main() { int main() {
uint64_t i = x.load(std::memory_order_relaxed); return x;
return std::atomic_is_lock_free(&x);
}" }"
LIBATOMIC_NOT_NEEDED) LIBATOMIC_NOT_NEEDED)
IF (NOT LIBATOMIC_NOT_NEEDED) IF (NOT LIBATOMIC_NOT_NEEDED)
set(ATOMIC_LIBRARY "atomic") set(ATOMIC_LIBRARY "atomic")
endif() endif()
IF (APPLE)
# Check if mbrtowc implementation attempts to encode invalid UTF-8 sequences
# Known culprits: at least some versions of macOS (confirmed Snow Leopard and Yosemite)
try_run(mbrtowc_invalid_utf8_exit mbrtowc_invalid_utf8_compiles ${CMAKE_CURRENT_BINARY_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/checks/mbrtowc_invalid_utf8.cpp")
IF ("${mbrtowc_invalid_utf8_compiles}" AND ("${mbrtowc_invalid_utf8_exit}" EQUAL 1))
SET(HAVE_BROKEN_MBRTOWC_UTF8 1)
ENDIF()
ENDIF()

View File

@@ -9,6 +9,7 @@ include(FeatureSummary)
set(SPHINX_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/doc_src") set(SPHINX_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/doc_src")
set(SPHINX_ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/user_doc") set(SPHINX_ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/user_doc")
set(SPHINX_BUILD_DIR "${SPHINX_ROOT_DIR}/build") set(SPHINX_BUILD_DIR "${SPHINX_ROOT_DIR}/build")
set(SPHINX_CACHE_DIR "${SPHINX_ROOT_DIR}/doctrees")
set(SPHINX_HTML_DIR "${SPHINX_ROOT_DIR}/html") set(SPHINX_HTML_DIR "${SPHINX_ROOT_DIR}/html")
set(SPHINX_MANPAGE_DIR "${SPHINX_ROOT_DIR}/man") set(SPHINX_MANPAGE_DIR "${SPHINX_ROOT_DIR}/man")
@@ -16,12 +17,13 @@ set(SPHINX_MANPAGE_DIR "${SPHINX_ROOT_DIR}/man")
# Prepend the output dir of fish_indent to PATH. # Prepend the output dir of fish_indent to PATH.
add_custom_target(sphinx-docs add_custom_target(sphinx-docs
mkdir -p ${SPHINX_HTML_DIR}/_static/ mkdir -p ${SPHINX_HTML_DIR}/_static/
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SPHINX_SRC_DIR}/_static/pygments.css ${SPHINX_HTML_DIR}/_static/
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SPHINX_SRC_DIR}/_static/custom.css ${SPHINX_HTML_DIR}/_static/
COMMAND env PATH="$<TARGET_FILE_DIR:fish_indent>:$$PATH" COMMAND env PATH="$<TARGET_FILE_DIR:fish_indent>:$$PATH"
${SPHINX_EXECUTABLE} ${SPHINX_EXECUTABLE}
-j auto
-q -b html -q -b html
-c "${SPHINX_SRC_DIR}" -c "${SPHINX_SRC_DIR}"
-d "${SPHINX_ROOT_DIR}/.doctrees-html" -d "${SPHINX_CACHE_DIR}"
"${SPHINX_SRC_DIR}" "${SPHINX_SRC_DIR}"
"${SPHINX_HTML_DIR}" "${SPHINX_HTML_DIR}"
DEPENDS ${SPHINX_SRC_DIR}/fish_indent_lexer.py fish_indent DEPENDS ${SPHINX_SRC_DIR}/fish_indent_lexer.py fish_indent
@@ -31,10 +33,9 @@ add_custom_target(sphinx-docs
add_custom_target(sphinx-manpages add_custom_target(sphinx-manpages
env PATH="$<TARGET_FILE_DIR:fish_indent>:$$PATH" env PATH="$<TARGET_FILE_DIR:fish_indent>:$$PATH"
${SPHINX_EXECUTABLE} ${SPHINX_EXECUTABLE}
-j auto
-q -b man -q -b man
-c "${SPHINX_SRC_DIR}" -c "${SPHINX_SRC_DIR}"
-d "${SPHINX_ROOT_DIR}/.doctrees-man" -d "${SPHINX_CACHE_DIR}"
"${SPHINX_SRC_DIR}" "${SPHINX_SRC_DIR}"
# TODO: This only works if we only have section 1 manpages. # TODO: This only works if we only have section 1 manpages.
"${SPHINX_MANPAGE_DIR}/man1" "${SPHINX_MANPAGE_DIR}/man1"

View File

@@ -14,8 +14,8 @@ set(bindir ${CMAKE_INSTALL_BINDIR})
set(sysconfdir ${CMAKE_INSTALL_SYSCONFDIR}) set(sysconfdir ${CMAKE_INSTALL_SYSCONFDIR})
set(mandir ${CMAKE_INSTALL_MANDIR}) set(mandir ${CMAKE_INSTALL_MANDIR})
set(rel_datadir ${CMAKE_INSTALL_DATADIR})
set(datadir ${CMAKE_INSTALL_FULL_DATADIR}) set(datadir ${CMAKE_INSTALL_FULL_DATADIR})
file(RELATIVE_PATH rel_datadir ${CMAKE_INSTALL_PREFIX} ${datadir})
set(docdir ${CMAKE_INSTALL_DOCDIR}) set(docdir ${CMAKE_INSTALL_DOCDIR})
@@ -91,9 +91,7 @@ fish_create_dirs(${rel_datadir}/fish ${rel_datadir}/fish/completions
${rel_datadir}/fish/tools/web_config ${rel_datadir}/fish/tools/web_config
${rel_datadir}/fish/tools/web_config/js ${rel_datadir}/fish/tools/web_config/js
${rel_datadir}/fish/tools/web_config/partials ${rel_datadir}/fish/tools/web_config/partials
${rel_datadir}/fish/tools/web_config/sample_prompts ${rel_datadir}/fish/tools/web_config/sample_prompts)
${rel_datadir}/fish/tools/web_config/themes
)
configure_file(share/__fish_build_paths.fish.in share/__fish_build_paths.fish) configure_file(share/__fish_build_paths.fish.in share/__fish_build_paths.fish)
install(FILES share/config.fish install(FILES share/config.fish
@@ -112,7 +110,7 @@ add_custom_command(OUTPUT fish.pc
COMMAND printf "Version: " >> fish.pc COMMAND printf "Version: " >> fish.pc
COMMAND sed 's/FISH_BUILD_VERSION=//\;s/\"//g' ${FBVF} >> fish.pc COMMAND sed 's/FISH_BUILD_VERSION=//\;s/\"//g' ${FBVF} >> fish.pc
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS CHECK-FISH-BUILD-VERSION-FILE ${CMAKE_CURRENT_BINARY_DIR}/fish.pc.noversion) DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${FBVF} ${CMAKE_CURRENT_BINARY_DIR}/fish.pc.noversion)
add_custom_target(build_fish_pc ALL DEPENDS fish.pc) add_custom_target(build_fish_pc ALL DEPENDS fish.pc)
@@ -149,7 +147,6 @@ install(DIRECTORY share/tools/web_config
PATTERN "*.html" PATTERN "*.html"
PATTERN "*.py" PATTERN "*.py"
PATTERN "*.js" PATTERN "*.js"
PATTERN "*.theme"
PATTERN "*.fish") PATTERN "*.fish")
# Building the man pages is optional: if Sphinx isn't installed, they're not built # Building the man pages is optional: if Sphinx isn't installed, they're not built
@@ -170,14 +167,13 @@ if(GETTEXT_FOUND)
endforeach() endforeach()
endif() endif()
if (NOT APPLE) install(FILES fish.desktop DESTINATION ${rel_datadir}/applications)
install(FILES fish.desktop DESTINATION ${rel_datadir}/applications) install(FILES fish.png DESTINATION ${rel_datadir}/pixmaps)
install(FILES ${SPHINX_SRC_DIR}/python_docs_theme/static/fish.png DESTINATION ${rel_datadir}/pixmaps)
endif()
# Group install targets into a InstallTargets folder # Group install targets into a InstallTargets folder
set_property(TARGET build_fish_pc CHECK-FISH-BUILD-VERSION-FILE set_property(TARGET build_fish_pc CHECK-FISH-BUILD-VERSION-FILE
tests_buildroot_target test_fishscript
test_prep tests_buildroot_target
PROPERTY FOLDER cmake/InstallTargets) PROPERTY FOLDER cmake/InstallTargets)
# Make a target build_root that installs into the buildroot directory, for testing. # Make a target build_root that installs into the buildroot directory, for testing.

View File

@@ -1,21 +1,13 @@
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.10" CACHE STRING "Minimum OS X deployment version") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
# Code signing ID on Mac. # Code signing ID on Mac. A default '-' is ad-hoc codesign.
# If this is falsey, codesigning is disabled. # If this is falsey, codesigning is disabled.
# '-' is ad-hoc codesign. set(MAC_CODESIGN_ID "-" CACHE STRING "Mac code-signing identity")
set(MAC_CODESIGN_ID "" CACHE STRING "Mac code-signing identity")
# Whether to inject the "get-task-allow" entitlement, which permits debugging # Whether to inject the "get-task-allow" entitlement, which permits debugging
# on the Mac. # on the Mac.
set(MAC_INJECT_GET_TASK_ALLOW ON CACHE BOOL "Inject get-task-allow on Mac") set(MAC_INJECT_GET_TASK_ALLOW ON CACHE BOOL "Inject get-task-allow on Mac")
# When building a Mac build, it is common for fish to link against a
# pcre2 built for the host platform (e.g. macOS 10.15) while fish wants
# to link for macOS 10.9. This warning would be of interest for releases,
# but is just noise for daily development. Unfortunately it has no flag
# of its own, so suppress all linker warnings in debug builds.
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -w")
function(CODESIGN_ON_MAC target) function(CODESIGN_ON_MAC target)
if((APPLE) AND (MAC_CODESIGN_ID)) if((APPLE) AND (MAC_CODESIGN_ID))
execute_process(COMMAND sw_vers "-productVersion" OUTPUT_VARIABLE OSX_VERSION) execute_process(COMMAND sw_vers "-productVersion" OUTPUT_VARIABLE OSX_VERSION)

View File

@@ -73,6 +73,3 @@ add_custom_target(signed_fish_macapp
$<TARGET_BUNDLE_DIR:fish_macapp> $<TARGET_BUNDLE_DIR:fish_macapp>
VERBATIM VERBATIM
) )
# Group our targets in a folder.
set_property(TARGET fish_macapp signed_fish_macapp PROPERTY FOLDER macapp)

View File

@@ -39,11 +39,5 @@ else()
add_subdirectory(pcre2 EXCLUDE_FROM_ALL) add_subdirectory(pcre2 EXCLUDE_FROM_ALL)
set(PCRE2_INCLUDE_DIR ${CMAKE_BINARY_DIR}/pcre2) set(PCRE2_INCLUDE_DIR ${CMAKE_BINARY_DIR}/pcre2)
set(PCRE2_LIB pcre2-${PCRE2_WIDTH}) set(PCRE2_LIB pcre2-${PCRE2_WIDTH})
# Disable -Wunused-macros inside PCRE2, as it is noisy.
get_target_property(PCRE2_COMPILE_OPTIONS ${PCRE2_LIB} COMPILE_OPTIONS)
list(REMOVE_ITEM PCRE2_COMPILE_OPTIONS "-Wunused-macros")
set_property(TARGET ${PCRE2_LIB} PROPERTY COMPILE_OPTIONS ${PCRE2_COMPILE_OPTIONS})
endif(FISH_USE_SYSTEM_PCRE2) endif(FISH_USE_SYSTEM_PCRE2)
include_directories(${PCRE2_INCLUDE_DIR}) include_directories(${PCRE2_INCLUDE_DIR})

View File

@@ -1,56 +1,4 @@
# This adds ctest support to the project # Define fish_tests.
enable_testing()
# By default, ctest runs tests serially
if(NOT CTEST_PARALLEL_LEVEL)
include(ProcessorCount)
ProcessorCount(CORES)
set(CTEST_PARALLEL_LEVEL ${CORES})
endif()
# Put in a tests folder to reduce the top level targets in IDEs.
set(CMAKE_FOLDER tests)
# We will use 125 as a reserved exit code to indicate that a test has been skipped, i.e. it did not
# pass but it should not be considered a failed test run, either.
set(SKIP_RETURN_CODE 125)
# Even though we are using CMake's ctest for testing, we still define our own `make test` target
# rather than use its default for many reasons:
# * CMake doesn't run tests in-proc or even add each tests as an individual node in the ninja
# dependency tree, instead it just bundles all tests into a target called `test` that always just
# shells out to `ctest`, so there are no build-related benefits to not doing that ourselves.
# * CMake devs insist that it is appropriate for `make test` to never depend on `make all`, i.e.
# running `make test` does not require any of the binaries to be built before testing.
# * The only way to have a test depend on a binary is to add a fake test with a name like
# "build_fish" that executes CMake recursively to build the `fish` target.
# * It is not possible to set top-level CTest options/settings such as CTEST_PARALLEL_LEVEL from
# within the CMake configuration file.
# * Circling back to the point about individual tests not being actual Makefile targets, CMake does
# not offer any way to execute a named test via the `make`/`ninja`/whatever interface; the only
# way to manually invoke test `foo` is to to manually run `ctest` and specify a regex matching
# `foo` as an argument, e.g. `ctest -R ^foo$`... which is really crazy.
# The top-level test target is "fish_run_tests".
add_custom_target(fish_run_tests
COMMAND env CTEST_PARALLEL_LEVEL=${CTEST_PARALLEL_LEVEL} FISH_FORCE_COLOR=1
FISH_SOURCE_DIR=${CMAKE_SOURCE_DIR}
${CMAKE_CTEST_COMMAND} --force-new-ctest-process # --verbose
--output-on-failure --progress
DEPENDS fish_tests tests_buildroot_target
USES_TERMINAL
)
# If CMP0037 is available, also make an alias "test" target.
# Note that this policy may not be available, in which case definining such a target silently fails.
cmake_policy(PUSH)
if(POLICY CMP0037)
cmake_policy(SET CMP0037 OLD)
add_custom_target(test DEPENDS fish_run_tests)
endif()
cmake_policy(POP)
# Build the low-level tests code
add_executable(fish_tests EXCLUDE_FROM_ALL add_executable(fish_tests EXCLUDE_FROM_ALL
src/fish_tests.cpp) src/fish_tests.cpp)
fish_link_deps_and_sign(fish_tests) fish_link_deps_and_sign(fish_tests)
@@ -58,43 +6,24 @@ fish_link_deps_and_sign(fish_tests)
# The "test" directory. # The "test" directory.
set(TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/test) set(TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/test)
# CMake doesn't really support dynamic test discovery where a test harness is executed to list the
# tests it contains, making fish_tests.cpp's tests opaque to CMake (whereas littlecheck tests can be
# enumerated from the filesystem). We used to compile fish_tests.cpp without linking against
# anything (-Wl,-undefined,dynamic_lookup,--unresolved-symbols=ignore-all) to get it to print its
# tests at configuration time, but that's a little too much dark CMake magic.
#
# We now identify tests by checking against a magic regex that's #define'd as a no-op C-side.
file(READ "${CMAKE_SOURCE_DIR}/src/fish_tests.cpp" FISH_TESTS_CPP)
string(REGEX MATCHALL "TEST_GROUP\\( *\"([^\"]+)\"" "LOW_LEVEL_TESTS" "${FISH_TESTS_CPP}")
string(REGEX REPLACE "TEST_GROUP\\( *\"([^\"]+)\"" "\\1" "LOW_LEVEL_TESTS" "${LOW_LEVEL_TESTS}")
list(REMOVE_DUPLICATES LOW_LEVEL_TESTS)
# The directory into which fish is installed. # The directory into which fish is installed.
set(TEST_INSTALL_DIR ${TEST_DIR}/buildroot) set(TEST_INSTALL_DIR ${TEST_DIR}/buildroot)
# The directory where the tests expect to find the fish root (./bin, etc) # The directory where the tests expect to find the fish root (./bin, etc)
set(TEST_ROOT_DIR ${TEST_DIR}/root) set(TEST_ROOT_DIR ${TEST_DIR}/root)
# Copy needed directories for out-of-tree builds # Copy tests files.
if(NOT FISH_IN_TREE_BUILD) file(GLOB TESTS_FILES tests/*)
add_custom_target(funcs_dir) add_custom_target(tests_dir DEPENDS tests)
add_custom_command(TARGET funcs_dir
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/share
# Don't run ln twice or it will create a new link in the link.
COMMAND test -e ${CMAKE_BINARY_DIR}/share/functions || ln -sf
${CMAKE_SOURCE_DIR}/share/functions/ ${CMAKE_BINARY_DIR}/share/functions
COMMENT "Symlinking fish functions to binary dir"
VERBATIM)
add_custom_target(tests_dir DEPENDS tests) if(NOT FISH_IN_TREE_BUILD)
add_custom_command(TARGET tests_dir add_custom_command(TARGET tests_dir
COMMAND ${CMAKE_COMMAND} -E copy_directory COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/tests/ ${CMAKE_BINARY_DIR}/tests/ ${CMAKE_SOURCE_DIR}/tests/ ${CMAKE_BINARY_DIR}/tests/
COMMENT "Copying test files to binary dir" COMMENT "Copying test files to binary dir"
VERBATIM) VERBATIM)
add_dependencies(fish_tests tests_dir funcs_dir) add_dependencies(fish_tests tests_dir)
endif() endif()
# Copy littlecheck.py # Copy littlecheck.py
@@ -103,73 +32,94 @@ configure_file(build_tools/littlecheck.py littlecheck.py COPYONLY)
# Copy pexpect_helper.py # Copy pexpect_helper.py
configure_file(build_tools/pexpect_helper.py pexpect_helper.py COPYONLY) configure_file(build_tools/pexpect_helper.py pexpect_helper.py COPYONLY)
# Suppress generating Xcode schemes for all tests, there's too many. # Make the directory in which to run tests.
set(CMAKE_XCODE_GENERATE_SCHEME 0) # Also symlink fish to where the tests expect it to be.
# Lastly put fish_test_helper there too.
# CMake being CMake, you can't just add a DEPENDS argument to add_test to make it depend on any of
# your binaries actually being built before `make test` is executed (requiring `make all` first),
# and the only dependency a test can have is on another test. So we make building fish and
# `fish_tests` prerequisites to our entire top-level `test` target.
function(add_test_target NAME)
string(REPLACE "/" "-" NAME ${NAME})
add_custom_target("test_${NAME}" COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -R "^${NAME}$$"
DEPENDS fish_tests tests_buildroot_target USES_TERMINAL )
endfunction()
add_custom_target(tests_buildroot_target add_custom_target(tests_buildroot_target
# Make the directory in which to run tests:
COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_INSTALL_DIR} COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_INSTALL_DIR}
COMMAND env DESTDIR=${TEST_INSTALL_DIR} ${CMAKE_COMMAND} COMMAND DESTDIR=${TEST_INSTALL_DIR} ${CMAKE_COMMAND}
--build ${CMAKE_CURRENT_BINARY_DIR} --target install --build ${CMAKE_CURRENT_BINARY_DIR} --target install
# Put fish_test_helper there too:
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/fish_test_helper COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/fish_test_helper
${TEST_INSTALL_DIR}/${CMAKE_INSTALL_PREFIX}/bin ${TEST_INSTALL_DIR}/${CMAKE_INSTALL_PREFIX}/bin
# Also symlink fish to where the tests expect it to be:
COMMAND ${CMAKE_COMMAND} -E create_symlink COMMAND ${CMAKE_COMMAND} -E create_symlink
${TEST_INSTALL_DIR}/${CMAKE_INSTALL_PREFIX} ${TEST_INSTALL_DIR}/${CMAKE_INSTALL_PREFIX}
${TEST_ROOT_DIR} ${TEST_ROOT_DIR}
DEPENDS fish fish_test_helper) DEPENDS fish fish_test_helper)
# CMake less than 3.9.0 "fully supports" setting an exit code to denote a skipped test, but then if(NOT FISH_IN_TREE_BUILD)
# it just goes ahead and reports it as failed. Really? # We need to symlink share/functions for the tests.
if(${CMAKE_VERSION} VERSION_LESS "3.9.0") # This should be simplified.
set(CMAKE_SKIPPED_HACK "env" "CMAKE_SKIPPED_HACK=1") add_custom_target(symlink_functions
COMMAND ${CMAKE_COMMAND} -E create_symlink
${CMAKE_CURRENT_SOURCE_DIR}/share/functions
${CMAKE_CURRENT_BINARY_DIR}/share/functions)
add_dependencies(tests_buildroot_target symlink_functions)
else() else()
set(CMAKE_SKIPPED_HACK) add_custom_target(symlink_functions)
endif() endif()
foreach(LTEST ${LOW_LEVEL_TESTS}) # Prep the environment for running the unit tests.
add_test( add_custom_target(test_prep
NAME ${LTEST} COMMAND ${CMAKE_COMMAND} -E remove_directory ${TEST_DIR}/data
COMMAND sh ${CMAKE_CURRENT_BINARY_DIR}/tests/test_env.sh COMMAND ${CMAKE_COMMAND} -E remove_directory ${TEST_DIR}/home
${CMAKE_BINARY_DIR}/fish_tests ${LTEST} COMMAND ${CMAKE_COMMAND} -E remove_directory ${TEST_DIR}/temp
COMMAND ${CMAKE_COMMAND} -E make_directory
${TEST_DIR}/data ${TEST_DIR}/home ${TEST_DIR}/temp
DEPENDS tests_buildroot_target tests_dir
USES_TERMINAL)
# Define our individual tests.
# Each test is conceptually independent.
# However when running all tests, we want to run them serially for sanity's sake.
# So define both a normal target, and a serial variant which enforces ordering.
foreach(TESTTYPE test serial_test)
add_custom_target(${TESTTYPE}_low_level
COMMAND env XDG_DATA_HOME=test/data XDG_CONFIG_HOME=test/home ./fish_tests
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
) DEPENDS fish_tests
set_tests_properties(${LTEST} PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE}) USES_TERMINAL)
add_test_target("${LTEST}")
endforeach(LTEST)
FILE(GLOB FISH_CHECKS CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/tests/checks/*.fish) add_custom_target(${TESTTYPE}_fishscript
foreach(CHECK ${FISH_CHECKS}) COMMAND cd tests && ${TEST_ROOT_DIR}/bin/fish test.fish
get_filename_component(CHECK_NAME ${CHECK} NAME) DEPENDS test_prep
get_filename_component(CHECK ${CHECK} NAME_WE) USES_TERMINAL)
add_test(NAME ${CHECK_NAME}
COMMAND ${CMAKE_SKIPPED_HACK} sh ${CMAKE_CURRENT_BINARY_DIR}/tests/test_driver.sh
${CMAKE_CURRENT_BINARY_DIR}/tests/test.fish ${CHECK}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tests
)
set_tests_properties(${CHECK_NAME} PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE})
add_test_target("${CHECK_NAME}")
endforeach(CHECK)
FILE(GLOB PEXPECTS CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/tests/pexpects/*.py) add_custom_target(${TESTTYPE}_interactive
foreach(PEXPECT ${PEXPECTS}) COMMAND cd tests && ${TEST_ROOT_DIR}/bin/fish interactive.fish
get_filename_component(PEXPECT ${PEXPECT} NAME) DEPENDS test_prep
add_test(NAME ${PEXPECT} USES_TERMINAL)
COMMAND ${CMAKE_SKIPPED_HACK} sh ${CMAKE_CURRENT_BINARY_DIR}/tests/test_driver.sh endforeach(TESTTYPE)
${CMAKE_CURRENT_BINARY_DIR}/tests/interactive.fish ${PEXPECT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tests # Now add a dependency chain between the serial versions.
) # This ensures they run in order.
set_tests_properties(${PEXPECT} PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE}) add_dependencies(serial_test_fishscript serial_test_low_level)
add_test_target("${PEXPECT}") add_dependencies(serial_test_interactive serial_test_fishscript)
endforeach(PEXPECT)
add_custom_target(serial_test_high_level
DEPENDS serial_test_interactive serial_test_fishscript)
# Create the 'test' target.
# Set a policy so CMake stops complaining about the name 'test'.
cmake_policy(PUSH)
if(${CMAKE_VERSION} VERSION_LESS 3.11.0 AND POLICY CMP0037)
cmake_policy(SET CMP0037 OLD)
endif()
add_custom_target(test)
cmake_policy(POP)
add_dependencies(test serial_test_high_level)
# Group test targets into a TestTargets folder
set_property(TARGET test tests_dir
test_low_level
test_fishscript
test_interactive
test_fishscript test_prep
tests_buildroot_target
serial_test_high_level
serial_test_low_level
serial_test_fishscript
serial_test_interactive
symlink_functions
PROPERTY FOLDER cmake/TestTargets)

View File

@@ -1,18 +0,0 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cwchar>
// Check whether the runtime mbrtowc implementation attempts to encode
// invalid UTF-8 values.
int main() {
// TODO: I'm not sure how to enforce a UTF-8 locale without overriding the language
char sample[] = "hello world";
sample[0] |= 0xF8;
wchar_t wsample[100] {};
std::mbstate_t state = std::mbstate_t();
int res = std::mbrtowc(wsample, sample, strlen(sample), &state);
return res < 0 ? 0 : 1;
}

View File

@@ -1,4 +1,4 @@
set(languages de en fr pl pt_BR sv zh_CN) set(languages de en fr nb nn pl pt_BR sv zh_CN)
include(FeatureSummary) include(FeatureSummary)
@@ -15,15 +15,12 @@ add_feature_info(gettext GETTEXT_FOUND "translate messages with gettext")
# Define translations # Define translations
if(GETTEXT_FOUND) if(GETTEXT_FOUND)
# Group pofile targets into their own folder, as there's a lot of them.
set(CMAKE_FOLDER pofiles)
foreach(lang ${languages}) foreach(lang ${languages})
# Our translations aren't set up entirely as CMake expects, so installation is done in # Our translations aren't set up entirely as CMake expects, so installation is done in
# cmake/Install.cmake instead of using INSTALL_DESTINATION # cmake/Install.cmake instead of using INSTALL_DESTINATION
gettext_process_po_files(${lang} ALL gettext_process_po_files(${lang} ALL
PO_FILES po/${lang}.po) PO_FILES po/${lang}.po)
endforeach() endforeach()
set(CMAKE_FOLDER)
endif() endif()
cmake_push_check_state() cmake_push_check_state()

View File

@@ -4,6 +4,9 @@
/* Define to 1 if compiled on WSL */ /* Define to 1 if compiled on WSL */
#cmakedefine WSL 1 #cmakedefine WSL 1
/* Define to 1 if you have the `clock_gettime' function. */
#cmakedefine HAVE_CLOCK_GETTIME 1
/* Define to 1 if you have the `ctermid_r' function. */ /* Define to 1 if you have the `ctermid_r' function. */
#cmakedefine HAVE_CTERMID_R 1 #cmakedefine HAVE_CTERMID_R 1
@@ -19,6 +22,12 @@
/* Define to 1 if you have the `flock' function. */ /* Define to 1 if you have the `flock' function. */
#cmakedefine HAVE_FLOCK 1 #cmakedefine HAVE_FLOCK 1
/* Define to 1 if you have the `futimens' function. */
#cmakedefine HAVE_FUTIMENS 1
/* Define to 1 if you have the `futimes' function. */
#cmakedefine HAVE_FUTIMES 1
/* Define to 1 if you have the `getifaddrs' function. */ /* Define to 1 if you have the `getifaddrs' function. */
#cmakedefine HAVE_GETIFADDRS 1 #cmakedefine HAVE_GETIFADDRS 1
@@ -34,6 +43,9 @@
/* Define to 1 if you have the `killpg' function. */ /* Define to 1 if you have the `killpg' function. */
#cmakedefine HAVE_KILLPG 1 #cmakedefine HAVE_KILLPG 1
/* Define to 1 if you have the `lrand48_r' function. */
#cmakedefine HAVE_LRAND48_R 1
/* Define to 1 if you have the `mkostemp' function. */ /* Define to 1 if you have the `mkostemp' function. */
#cmakedefine HAVE_MKOSTEMP 1 #cmakedefine HAVE_MKOSTEMP 1
@@ -49,12 +61,6 @@
/* Define to 1 if you have the <ncurses/term.h> header file. */ /* Define to 1 if you have the <ncurses/term.h> header file. */
#cmakedefine HAVE_NCURSES_TERM_H 1 #cmakedefine HAVE_NCURSES_TERM_H 1
/* Define to 1 if you have the 'eventfd' function. */
#cmakedefine HAVE_EVENTFD 1
/* Define to 1 if you have the 'pipe2' function. */
#cmakedefine HAVE_PIPE2 1
/* Define to 1 if you have the <siginfo.h> header file. */ /* Define to 1 if you have the <siginfo.h> header file. */
#cmakedefine HAVE_SIGINFO_H 1 #cmakedefine HAVE_SIGINFO_H 1
@@ -82,6 +88,9 @@
/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */ /* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1 #cmakedefine HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1
/* Define to 1 if the sys_errlist array is available. */
#cmakedefine HAVE_SYS_ERRLIST 1
/* Define to 1 if you have the <sys/ioctl.h> header file. */ /* Define to 1 if you have the <sys/ioctl.h> header file. */
#cmakedefine HAVE_SYS_IOCTL_H 1 #cmakedefine HAVE_SYS_IOCTL_H 1
@@ -91,6 +100,9 @@
/* Define to 1 if you have the <sys/sysctl.h> header file. */ /* Define to 1 if you have the <sys/sysctl.h> header file. */
#cmakedefine HAVE_SYS_SYSCTL_H 1 #cmakedefine HAVE_SYS_SYSCTL_H 1
/* Define to 1 if you have the <termios.h> header file. */
#cmakedefine HAVE_TERMIOS_H 1
/* Define to 1 if you have the <term.h> header file. */ /* Define to 1 if you have the <term.h> header file. */
#cmakedefine HAVE_TERM_H 1 #cmakedefine HAVE_TERM_H 1
@@ -121,8 +133,8 @@
/* Define to 1 if std::make_unique is available. */ /* Define to 1 if std::make_unique is available. */
#cmakedefine HAVE_STD__MAKE_UNIQUE 1 #cmakedefine HAVE_STD__MAKE_UNIQUE 1
/* Define to use clock_gettime and futimens to hack around Linux mtime issue */ /* Define to 1 if the _sys_errs array is available. */
#cmakedefine UVAR_FILE_SET_MTIME_HACK 1 #cmakedefine HAVE__SYS__ERRS 1
/* Define to 1 to disable ncurses macros that conflict with the STL */ /* Define to 1 to disable ncurses macros that conflict with the STL */
#define NCURSES_NOMACROS 1 #define NCURSES_NOMACROS 1
@@ -139,9 +151,6 @@
/* Use a variadic tparm on NetBSD curses. */ /* Use a variadic tparm on NetBSD curses. */
#cmakedefine TPARM_VARARGS 1 #cmakedefine TPARM_VARARGS 1
/* The parameter type for the last tputs parameter */
#cmakedefine TPUTS_USES_INT_ARG 1
/* Define to 1 if tparm accepts a fixed amount of parameters. */ /* Define to 1 if tparm accepts a fixed amount of parameters. */
#cmakedefine TPARM_SOLARIS_KLUDGE 1 #cmakedefine TPARM_SOLARIS_KLUDGE 1
@@ -156,18 +165,11 @@
/* Define if xlocale.h is required for locale_t or wide character support */ /* Define if xlocale.h is required for locale_t or wide character support */
#cmakedefine HAVE_XLOCALE_H 1 #cmakedefine HAVE_XLOCALE_H 1
/* Define if uselocale is available */
#cmakedefine HAVE_USELOCALE 1
/* Enable large inode numbers on Mac OS X 10.5. */ /* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE #ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1 # define _DARWIN_USE_64_BIT_INODE 1
#endif #endif
/* Define to 1 if mbrtowc attempts to convert invalid UTF-8 sequences */
#cmakedefine HAVE_BROKEN_MBRTOWC_UTF8 1
/* Support __warn_unused on function return values. */
#if __GNUC__ >= 3 #if __GNUC__ >= 3
#ifndef __warn_unused #ifndef __warn_unused
#define __warn_unused __attribute__ ((warn_unused_result)) #define __warn_unused __attribute__ ((warn_unused_result))
@@ -175,26 +177,3 @@
#else #else
#define __warn_unused #define __warn_unused
#endif #endif
/* Like __warn_unused, but applies to a type.
At the moment only clang supports this as a type attribute.
We need to check for __has_attribute being a thing before or old gcc fails - #7554.
*/
#ifndef __has_attribute
#define __has_attribute(x) 0 // Compatibility with non-clang and old gcc compilers.
#endif
#if defined(__clang__) && __has_attribute(warn_unused_result)
#ifndef __warn_unused_type
#define __warn_unused_type __attribute__ ((warn_unused_result))
#endif
#else
#define __warn_unused_type
#endif
#if __has_attribute(fallthrough)
#define __fallthrough__ __attribute__ ((fallthrough));
#else
#define __fallthrough__
#endif

2
debian/compat vendored
View File

@@ -1 +1 @@
10 9

34
debian/control vendored
View File

@@ -3,10 +3,10 @@ Section: shells
Priority: optional Priority: optional
Maintainer: ridiculous_fish <corydoras@ridiculousfish.com> Maintainer: ridiculous_fish <corydoras@ridiculousfish.com>
Uploaders: David Adam <zanchey@ucc.gu.uwa.edu.au> Uploaders: David Adam <zanchey@ucc.gu.uwa.edu.au>
# Debhelper should be bumped to >= 10 once Ubuntu Xenial is no longer supported Build-Depends: debhelper (>= 9.20151004), libncurses5-dev, cmake (>= 3.2.0), gettext,
Build-Depends: debhelper (>= 9.20160115), libncurses5-dev, cmake (>= 3.5.0), gettext, libpcre2-dev,
# Test dependencies # Test dependencies
locales-all, python3 locales-all, python3
# When libpcre2-dev is available on all supported Debian versions, add a dependency on that.
Standards-Version: 4.1.5 Standards-Version: 4.1.5
Homepage: https://fishshell.com/ Homepage: https://fishshell.com/
Vcs-Git: https://github.com/fish-shell/fish-shell.git Vcs-Git: https://github.com/fish-shell/fish-shell.git
@@ -14,12 +14,34 @@ Vcs-Browser: https://github.com/fish-shell/fish-shell
Package: fish Package: fish
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, passwd (>= 4.0.3-10), gettext-base, man-db, Depends: ${shlibs:Depends}, ${misc:Depends}, fish-common (= ${source:Version}), passwd (>= 4.0.3-10), gettext-base, man-db
python3 (>=3.5)
Conflicts: fish-common
Recommends: xsel (>=1.2.0) Recommends: xsel (>=1.2.0)
Suggests: xdg-utils
Description: friendly interactive shell Description: friendly interactive shell
Fish is a command-line shell for modern systems, focusing on user-friendliness, Fish is a command-line shell for modern systems, focusing on user-friendliness,
sensibility and discoverability in interactive use. The syntax is simple, but sensibility and discoverability in interactive use. The syntax is simple, but
not POSIX compliant. not POSIX compliant.
Package: fish-common
Architecture: all
Multi-Arch: foreign
Depends: ${misc:Depends}
Recommends: fish, python3 (>= 3.5), python3-distutils
Suggests: xdg-utils
Replaces: fish (<= 2.1.1.dfsg-2)
Description: friendly interactive shell (architecture-independent files)
Fish is a command-line shell for modern systems, focusing on user-friendliness,
sensibility and discoverability in interactive use. The syntax is simple, but
not POSIX compliant.
.
This package contains the common fish files shared by all architectures.
Package: fish-dbg
Architecture: any
Section: debug
Depends: fish (= ${binary:Version}), ${misc:Depends}
Description: debugging symbols for friendly interactive shell
Fish is a command-line shell for modern systems, focusing on user-friendliness,
sensibility and discoverability in interactive use. The syntax is simple, but
not POSIX compliant.
.
This package contains the debugging symbols for fish.

2
debian/fish-common.install vendored Normal file
View File

@@ -0,0 +1,2 @@
debian/tmp/etc
debian/tmp/usr/share

4
debian/fish-common.lintian-overrides vendored Normal file
View File

@@ -0,0 +1,4 @@
# These directories are intentionally empty.
fish-common: package-contains-empty-directory usr/share/fish/vendor_completions.d/
fish-common: package-contains-empty-directory usr/share/fish/vendor_conf.d/
fish-common: package-contains-empty-directory usr/share/fish/vendor_functions.d/

1
debian/fish.install vendored Normal file
View File

@@ -0,0 +1 @@
debian/tmp/usr/bin

37
debian/fish.postrm vendored Normal file
View File

@@ -0,0 +1,37 @@
#!/bin/sh
# postrm script for fish
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postrm> `remove'
# * <postrm> `purge'
# * <old-postrm> `upgrade' <new-version>
# * <new-postrm> `failed-upgrade' <old-version>
# * <new-postrm> `abort-install'
# * <new-postrm> `abort-install' <old-version>
# * <new-postrm> `abort-upgrade' <old-version>
# * <disappearer's-postrm> `disappear' <overwriter>
# <overwriter-version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
;;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

View File

View File

@@ -1,4 +0,0 @@
# These directories are intentionally empty.
fish: package-contains-empty-directory usr/share/fish/vendor_completions.d/
fish: package-contains-empty-directory usr/share/fish/vendor_conf.d/
fish: package-contains-empty-directory usr/share/fish/vendor_functions.d/

13
debian/rules vendored
View File

@@ -9,9 +9,12 @@ export DH_VERBOSE=1
# Setting the build system is still required, because otherwise the GNUmakefile gets picked up # Setting the build system is still required, because otherwise the GNUmakefile gets picked up
override_dh_auto_configure: override_dh_auto_configure:
dh_auto_configure --buildsystem=cmake dh_auto_configure --buildsystem=cmake --parallel
# On CMake 3.5 (and possibly 3.6), the test target does not pick up its dependencies properly override_dh_installdocs:
# Build fish_tests/tests_buildroot_target by hand (remove this once Ubuntu Xenial is out of support) dh_installdocs --link-doc=fish
override_dh_auto_build:
dh_auto_build -- all fish_tests tests_buildroot_target # Still needed until all platforms have debhelper 9.20151219
# Consider transitioning https://wiki.debian.org/DebugPackage
override_dh_strip:
dh_strip --dbg-package=fish-dbg

View File

@@ -1,4 +1,4 @@
Release notes CHANGELOG
############# #########
.. include:: ../CHANGELOG.rst .. include:: ../CHANGELOG.rst

View File

@@ -0,0 +1,10 @@
.sphinxsidebar ul.current > li.current { font-weight: bold }
kbd {
background-color: #f9f9f9;
border: 1px solid #aaa;
border-radius: .2em;
box-shadow: 0.1em 0.1em 0.2em rgba(0,0,0,0.1);
color: #000;
padding: 0.1em 0.3em;
}

View File

@@ -1,20 +1,30 @@
@import "nature.css";
.highlight .hll { background-color: #ffffcc } .highlight .hll { background-color: #ffffcc }
.highlight { background: #f8f8f8; }
.highlight .c { color: #8f5902; } /* Comment */
.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ .highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */
.highlight .g { color: #000000 } /* Generic */
.highlight .k { color: #204a87; font-weight: bold } /* Keyword */ .highlight .k { color: #204a87; font-weight: bold } /* Keyword */
.highlight .l { color: #000000 } /* Literal */
.highlight .n { color: #000000 } /* Name */
.highlight .o { color: #00a6b2; } /* Operator */ .highlight .o { color: #00a6b2; } /* Operator */
.highlight .p { color: #00bfff; } /* Punctuation */ .highlight .x { color: #000000 } /* Other */
.highlight .c { color: #777; font-style: italic; } /* Comment */ .highlight .p { color: #00afff; } /* Punctuation */
.highlight .ch { color: #8f7902; font-style: italic } /* Comment.Hashbang */ .highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #8f7902; font-style: italic } /* Comment.Multiline */ .highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #8f7902; font-style: italic } /* Comment.Preproc */ .highlight .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */
.highlight .cpf { color: #8f7902; font-style: italic } /* Comment.PreprocFile */ .highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #8f7902; font-style: italic } /* Comment.Single */ .highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */
.highlight .cs { color: #8f7902; font-style: italic } /* Comment.Special */ .highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */
.highlight .gd { color: #a40000 } /* Generic.Deleted */ .highlight .gd { color: #a40000 } /* Generic.Deleted */
.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */
.highlight .gr { color: #ef2929 } /* Generic.Error */ .highlight .gr { color: #ef2929 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */ .highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .gp { color: #8f7902 } /* Generic.Prompt */ .highlight .go { color: #000000; font-style: italic } /* Generic.Output */
.highlight .gp { color: #8f5902 } /* Generic.Prompt */
.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ .highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */
.highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */ .highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */
@@ -23,17 +33,23 @@
.highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */ .highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */ .highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */ .highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */
.highlight .ld { color: #000000 } /* Literal.Date */
.highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */ .highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */
.highlight .s { color: #4e9a06 } /* Literal.String */ .highlight .s { color: #4e9a06 } /* Literal.String */
.highlight .na { color: #c4a000 } /* Name.Attribute */ .highlight .na { color: #c4a000 } /* Name.Attribute */
.highlight .nb { color: #204a87 } /* Name.Builtin */ .highlight .nb { color: #204a87 } /* Name.Builtin */
.highlight .no { color: #00bfff } /* Name.Constant */ .highlight .nc { color: #000000 } /* Name.Class */
.highlight .no { color: #00afff } /* Name.Constant */
.highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */ .highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */
.highlight .ni { color: #ce5c00 } /* Name.Entity */ .highlight .ni { color: #ce5c00 } /* Name.Entity */
.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ .highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #005fd7 } /* Name.Function */ .highlight .nf { color: #005fd7 } /* Name.Function */
.highlight .nl { color: #f57900 } /* Name.Label */ .highlight .nl { color: #f57900 } /* Name.Label */
.highlight .nn { color: #000000 } /* Name.Namespace */
.highlight .nx { color: #000000 } /* Name.Other */
.highlight .py { color: #000000 } /* Name.Property */
.highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */ .highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #000000 } /* Name.Variable */
.highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */ .highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */
.highlight .w { color: #f8f8f8; } /* Text.Whitespace */ .highlight .w { color: #f8f8f8; } /* Text.Whitespace */
.highlight .mb { color: #0000cf; font-weight: bold } /* Literal.Number.Bin */ .highlight .mb { color: #0000cf; font-weight: bold } /* Literal.Number.Bin */
@@ -45,47 +61,24 @@
.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ .highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */
.highlight .sc { color: #4e9a06 } /* Literal.String.Char */ .highlight .sc { color: #4e9a06 } /* Literal.String.Char */
.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ .highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */
.highlight .sd { color: #8f7902; font-style: italic } /* Literal.String.Doc */ .highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #4daf08 } /* Literal.String.Double */ .highlight .s2 { color: #999900 } /* Literal.String.Double */
.highlight .se { color: #00a6b2 } /* Literal.String.Escape */ .highlight .se { color: #00a6b2 } /* Literal.String.Escape */
.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ .highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */
.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ .highlight .si { color: #4e9a06 } /* Literal.String.Interpol */
.highlight .sx { color: #4e9a06 } /* Literal.String.Other */ .highlight .sx { color: #4e9a06 } /* Literal.String.Other */
.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ .highlight .sr { color: #4e9a06 } /* Literal.String.Regex */
.highlight .s1 { color: #d0d00b } /* Literal.String.Single */ .highlight .s1 { color: #999900 } /* Literal.String.Single */
.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ .highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */
.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ .highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #000000 } /* Name.Function.Magic */
.highlight .vc { color: #000000 } /* Name.Variable.Class */
.highlight .vg { color: #000000 } /* Name.Variable.Global */
.highlight .vi { color: #000000 } /* Name.Variable.Instance */
.highlight .vm { color: #000000 } /* Name.Variable.Magic */
.highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */ .highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */
.purple { color: #551a8b }
:root { .yellow { color: #FFFF00 }
/* custom property */ .red { color: #FF0000 }
--contrast: #000000; .gray { color: #555555 }
} .underline { text-decoration: underline }
@media (prefers-color-scheme: dark) {
:root {
--contrast: #FFFFFF;
}
.highlight .k { color: #507a97; font-weight: bold } /* Keyword */
.highlight .nf { color: #008fd7 } /* Name.Function */
.highlight .nb { color: #209a87 } /* Name.Builtin */
.highlight .s2 { color: #9ce781 } /* Literal.String.Double */
}
.highlight .g { color: var(--contrast) } /* Generic */
.highlight .l { color: var(--contrast) } /* Literal */
.highlight .n { color: var(--contrast) } /* Name */
.highlight .x { color: var(--contrast) } /* Other */
.highlight .ge { color: var(--contrast); font-style: italic } /* Generic.Emph */
.highlight .go { color: var(--contrast); font-style: italic } /* Generic.Output */
.highlight .gs { color: var(--contrast); font-weight: bold } /* Generic.Strong */
.highlight .ld { color: var(--contrast) } /* Literal.Date */
.highlight .nc { color: var(--contrast) } /* Name.Class */
.highlight .nn { color: var(--contrast) } /* Name.Namespace */
.highlight .nx { color: var(--contrast) } /* Name.Other */
.highlight .py { color: var(--contrast) } /* Name.Property */
.highlight .nv { color: var(--contrast) } /* Name.Variable */
.highlight .fm { color: var(--contrast) } /* Name.Function.Magic */
.highlight .vc { color: var(--contrast) } /* Name.Variable.Class */
.highlight .vg { color: var(--contrast) } /* Name.Variable.Global */
.highlight .vi { color: var(--contrast) } /* Name.Variable.Instance */
.highlight .vm { color: var(--contrast) } /* Name.Variable.Magic */

View File

@@ -6,9 +6,9 @@ _ - call fish's translations
Synopsis Synopsis
-------- --------
.. synopsis:: ::
_ STRING _ STRING...
Description Description
----------- -----------
@@ -19,17 +19,19 @@ It is equivalent to ``gettext fish STRING``, meaning it can only be used to look
It requires fish to be built with gettext support. If that support is disabled, or there is no translation it will simply echo the argument back. It requires fish to be built with gettext support. If that support is disabled, or there is no translation it will simply echo the argument back.
The language depends on the current locale, set with :envvar:`LANG` and :envvar:`LC_MESSAGES`. The language depends on the current locale, set with ``$LANG`` and ``$LC_MESSAGES``.
Options Options
------- -------
``_`` takes no options. ``_`` has no options.
Examples Examples
-------- --------
:: ::
> _ File > _ File

View File

@@ -6,75 +6,66 @@ abbr - manage fish abbreviations
Synopsis Synopsis
-------- --------
.. synopsis:: ::
abbr --add [SCOPE] WORD EXPANSION abbr --add [SCOPE] WORD EXPANSION
abbr --erase WORD ... abbr --erase WORD
abbr --rename [SCOPE] OLD_WORD NEW_WORD abbr --rename [SCOPE] OLD_WORD NEW_WORD
abbr --show abbr --show
abbr --list abbr --list
abbr --query WORD ... abbr --query WORD...
Description Description
----------- -----------
``abbr`` manages abbreviations - user-defined words that are replaced with longer phrases after they are entered. ``abbr`` manages abbreviations - user-defined words that are replaced with longer phrases after they are entered.
For example, a frequently-run command like ``git checkout`` can be abbreviated to ``gco``. For example, a frequently-run command like ``git checkout`` can be abbreviated to ``gco``. After entering ``gco`` and pressing :kbd:`Space` or :kbd:`Enter`, the full text ``git checkout`` will appear in the command line.
After entering ``gco`` and pressing :kbd:`Space` or :kbd:`Enter`, the full text ``git checkout`` will appear in the command line.
Options Options
------- -------
The following options are available: The following options are available:
**-a** *WORD* *EXPANSION* or **--add** *WORD* *EXPANSION* - ``-a WORD EXPANSION`` or ``--add WORD EXPANSION`` Adds a new abbreviation, causing WORD to be expanded to EXPANSION.
Adds a new abbreviation, causing *WORD* to be expanded to *EXPANSION*
**-r** *OLD_WORD* *NEW_WORD* or **--rename** *OLD_WORD* *NEW_WORD* - ``-r OLD_WORD NEW_WORD`` or ``--rename OLD_WORD NEW_WORD`` Renames an abbreviation, from OLD_WORD to NEW_WORD.
Renames an abbreviation, from *OLD_WORD* to *NEW_WORD*
**-s** or **--show** - ``-s`` or ``--show`` Show all abbreviations in a manner suitable for export and import.
Show all abbreviations in a manner suitable for import and export
**-l** or **--list** - ``-l`` or ``--list`` Lists all abbreviated words.
Lists all abbreviated words
**-e** *WORD* or **--erase** *WORD* ... - ``-e WORD`` or ``--erase WORD`` Erase the abbreviation WORD.
Erase the given abbreviations
**-q** or **--query** - ``-q`` or ``--query`` Return 0 (true) if one of the WORDs is an abbreviation.
Return 0 (true) if one of the *WORD* is an abbreviation.
**-h** or **--help** In addition, when adding or renaming abbreviations:
Displays help about using this command.
In addition, when adding or renaming abbreviations, one of the following **SCOPE** options can be used: - ``-g`` or ``--global`` to use a global variable.
- ``-U`` or ``--universal`` to use a universal variable (default).
**-g** or **--global**
Use a global variable
**-U** or **--universal**
Use a universal variable (default)
See the "Internals" section for more on them. See the "Internals" section for more on them.
Examples Examples
-------- --------
:: ::
abbr -a -g gco git checkout abbr -a -g gco git checkout
Add a new abbreviation where ``gco`` will be replaced with ``git checkout`` global to the current shell. Add a new abbreviation where ``gco`` will be replaced with ``git checkout`` global to the current shell. This abbreviation will not be automatically visible to other shells unless the same command is run in those shells (such as when executing the commands in config.fish).
This abbreviation will not be automatically visible to other shells unless the same command is run in those shells (such as when executing the commands in config.fish).
:: ::
abbr -a -U l less abbr -a -U l less
Add a new abbreviation where ``l`` will be replaced with ``less`` universal to all shells. Add a new abbreviation where ``l`` will be replaced with ``less`` universal so all shells. Note that you omit the ``-U`` since it is the default.
Note that you omit the **-U** since it is the default.
:: ::
@@ -82,12 +73,16 @@ Note that you omit the **-U** since it is the default.
Renames an existing abbreviation from ``gco`` to ``gch``. Renames an existing abbreviation from ``gco`` to ``gch``.
:: ::
abbr -e gco abbr -e gco
Erase the ``gco`` abbreviation. Erase the ``gco`` abbreviation.
:: ::
ssh another_host abbr -s | source ssh another_host abbr -s | source
@@ -96,8 +91,20 @@ Import the abbreviations defined on another_host over SSH.
Internals Internals
--------- ---------
Each abbreviation is stored in its own global or universal variable. Each abbreviation is stored in its own global or universal variable. The name consists of the prefix ``_fish_abbr_`` followed by the WORD after being transformed by ``string escape style=var``. The WORD cannot contain a space but all other characters are legal.
The name consists of the prefix ``_fish_abbr_`` followed by the WORD after being transformed by ``string escape style=var``.
The WORD cannot contain a space but all other characters are legal.
Abbreviations created with the **--universal** flag will be visible to other fish sessions, whilst **--global** will be limited to the current session. Defining an abbreviation with global scope is slightly faster than universal scope (which is the default). But in general you'll only want to use the global scope when defining abbreviations in a startup script like ``~/.config/fish/config.fish`` like this:
::
if status --is-interactive
abbr --add --global first 'echo my first abbreviation'
abbr --add --global second 'echo my second abbreviation'
abbr --add --global gco git checkout
# etcetera
end
You can create abbreviations interactively and they will be visible to other fish sessions if you use the ``-U`` or ``--universal`` flag or don't explicitly specify the scope and the abbreviation isn't already defined with global scope. If you want it to be visible only to the current shell use the ``-g`` or ``--global`` flag.

View File

@@ -6,11 +6,11 @@ alias - create a function
Synopsis Synopsis
-------- --------
.. synopsis:: ::
alias alias
alias [--save] NAME DEFINITION alias [OPTIONS] NAME DEFINITION
alias [--save] NAME=DEFINITION alias [OPTIONS] NAME=DEFINITION
Description Description
@@ -21,23 +21,23 @@ Description
``fish`` marks functions that have been created by ``alias`` by including the command used to create them in the function description. You can list ``alias``-created functions by running ``alias`` without arguments. They must be erased using ``functions -e``. ``fish`` marks functions that have been created by ``alias`` by including the command used to create them in the function description. You can list ``alias``-created functions by running ``alias`` without arguments. They must be erased using ``functions -e``.
- ``NAME`` is the name of the alias - ``NAME`` is the name of the alias
- ``DEFINITION`` is the actual command to execute. ``alias`` automatically appends ``$argv``, so that all parameters used with the alias are passed to the actual command. - ``DEFINITION`` is the actual command to execute. The string ``$argv`` will be appended.
You cannot create an alias to a function with the same name. Note that spaces need to be escaped in the call to ``alias`` just like at the command line, *even inside quoted parts*. You cannot create an alias to a function with the same name. Note that spaces need to be escaped in the call to ``alias`` just like at the command line, *even inside quoted parts*.
The following options are available: The following options are available:
**-h** or **--help** - ``-h`` or ``--help`` displays help about using this command.
Displays help about using this command.
**-s** or **--save** - ``-s`` or ``--save`` Automatically save the function created by the alias into your fish configuration directory using :ref:`funcsave <cmd-funcsave>`.
Saves the function created by the alias into your fish configuration directory using :ref:`funcsave <cmd-funcsave>`.
Example Example
------- -------
The following code will create ``rmi``, which runs ``rm`` with additional arguments on every invocation. The following code will create ``rmi``, which runs ``rm`` with additional arguments on every invocation.
:: ::
alias rmi="rm -i" alias rmi="rm -i"
@@ -47,14 +47,6 @@ The following code will create ``rmi``, which runs ``rm`` with additional argume
rm -i $argv rm -i $argv
end end
# This needs to have the spaces escaped or "Chrome.app..." # This needs to have the spaces escaped or "Chrome.app..." will be seen as an argument to "/Applications/Google":
# will be seen as an argument to "/Applications/Google":
alias chrome='/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome banana' alias chrome='/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome banana'
See more
--------
1. The :ref:`function <cmd-function>` command this builds on.
2. :ref:`Functions <syntax-function>`.
3. :ref:`Function wrappers <syntax-function-wrappers>`.

View File

@@ -6,9 +6,9 @@ and - conditionally execute a command
Synopsis Synopsis
-------- --------
.. synopsis:: ::
PREVIOUS; and COMMAND COMMAND1; and COMMAND2
Description Description
----------- -----------
@@ -19,8 +19,6 @@ Description
``and`` does not change the current exit status itself, but the command it runs most likely will. The exit status of the last foreground command to exit can always be accessed using the :ref:`$status <variables-status>` variable. ``and`` does not change the current exit status itself, but the command it runs most likely will. The exit status of the last foreground command to exit can always be accessed using the :ref:`$status <variables-status>` variable.
The **-h** or **--help** option displays help about using this command.
Example Example
------- -------
@@ -34,4 +32,3 @@ See Also
-------- --------
- :ref:`or <cmd-or>` command - :ref:`or <cmd-or>` command
- :ref:`not <cmd-not>` command

View File

@@ -6,144 +6,127 @@ argparse - parse options passed to a fish script or function
Synopsis Synopsis
-------- --------
.. synopsis:: ::
argparse [OPTIONS] OPTION_SPEC ... -- [ARG ...] argparse [OPTIONS] OPTION_SPEC... -- [ARG...]
Description Description
----------- -----------
This command makes it easy for fish scripts and functions to handle arguments. You pass arguments that define the known options, followed by a literal **--**, then the arguments to be parsed (which might also include a literal **--**). ``argparse`` then sets variables to indicate the passed options with their values, and sets ``$argv`` to the remaining arguments. See the :ref:`usage <cmd-argparse-usage>` section below. This command makes it easy for fish scripts and functions to handle arguments like how fish builtin commands handle their arguments. You pass arguments that define the known options, followed by a literal ``--``, then the arguments to be parsed (which might also include a literal ``--``). ``argparse`` then sets variables to indicate the passed options with their values, and sets $argv (and always $argv) to the remaining arguments. More on this in the `usage <#usage>`__ section below.
Each option specification (``OPTION_SPEC``) is written in the :ref:`domain specific language <cmd-argparse-option-specification>` described below. All OPTION_SPECs must appear after any argparse flags and before the ``--`` that separates them from the arguments to be parsed. Each option specification (``OPTION_SPEC``) is written in the `domain specific language <#option-specifications>`__ described below. All OPTION_SPECs must appear after any argparse flags and before the ``--`` that separates them from the arguments to be parsed.
Each option that is seen in the ARG list will result in variables named ``_flag_X``, where **X** is the short flag letter and the long flag name (if they are defined). For example a **--help** option could cause argparse to define one variable called ``_flag_h`` and another called ``_flag_help``. Each option that is seen in the ARG list will result in a var name of the form ``_flag_X``, where ``X`` is the short flag letter and the long flag name. The OPTION_SPEC always requires a short flag even if it can't be used. So there will always be ``_flag_X`` var set using the short flag letter if the corresponding short or long flag is seen. The long flag name var (e.g., ``_flag_help``) will only be defined, obviously, if the OPTION_SPEC includes a long flag name.
The variables will be set with local scope (i.e., as if the script had done ``set -l _flag_X``). If the flag is a boolean (that is, it just is passed or not, it doesn't have a value) the values are the short and long flags seen. If the option is not a boolean the values will be zero or more values corresponding to the values collected when the ARG list is processed. If the flag was not seen the flag variable will not be set. For example ``_flag_h`` and ``_flag_help`` if ``-h`` or ``--help`` is seen. The var will be set with local scope (i.e., as if the script had done ``set -l _flag_X``). If the flag is a boolean (that is, it just is passed or not, it doesn't have a value) the values are the short and long flags seen. If the option is not a boolean the values will be zero or more values corresponding to the values collected when the ARG list is processed. If the flag was not seen the flag var will not be set.
Options Options
------- -------
The following ``argparse`` options are available. They must appear before all *OPTION_SPEC*\ s: The following ``argparse`` options are available. They must appear before all OPTION_SPECs:
**-n** or **--name** - ``-n`` or ``--name`` is the command name for use in error messages. By default the current function name will be used, or `argparse` if run outside of a function.
The command name for use in error messages. By default the current function name will be used, or ``argparse`` if run outside of a function.
**-x** or **--exclusive** *OPTIONS* - ``-x`` or ``--exclusive`` should be followed by a comma separated list of short or long options that are mutually exclusive. You can use this more than once to define multiple sets of mutually exclusive options.
A comma separated list of options that are mutually exclusive. You can use this more than once to define multiple sets of mutually exclusive options.
**-N** or **--min-args** *NUMBER* - ``-N`` or ``--min-args`` is followed by an integer that defines the minimum number of acceptable non-option arguments. The default is zero.
The minimum number of acceptable non-option arguments. The default is zero.
**-X** or **--max-args** *NUMBER* - ``-X`` or ``--max-args`` is followed by an integer that defines the maximum number of acceptable non-option arguments. The default is infinity.
The maximum number of acceptable non-option arguments. The default is infinity.
**-i** or **--ignore-unknown** - ``-i`` or ``--ignore-unknown`` ignores unknown options, keeping them and their arguments in $argv instead.
Ignores unknown options, keeping them and their arguments in $argv instead.
**-s** or **--stop-nonopt** - ``-s`` or ``--stop-nonopt`` causes scanning the arguments to stop as soon as the first non-option argument is seen. Among other things, this is useful to implement subcommands that have their own options.
Causes scanning the arguments to stop as soon as the first non-option argument is seen. Among other things, this is useful to implement subcommands that have their own options.
**-h** or **--help** - ``-h`` or ``--help`` displays help about using this command.
Displays help about using this command.
.. _cmd-argparse-usage:
Usage Usage
----- -----
To use this command, pass the option specifications (**OPTION_SPEC**), a mandatory **--**, and then the arguments to be parsed. Using this command requires first passing option specifications (``OPTION_SPEC`` below), then a mandatory ``--``, and then the arguments you want to have parsed. More about this below but here is a simple example that might be used in a function named ``my_function``:
A simple example::
::
argparse --name=my_function 'h/help' 'n/name=' -- $argv argparse --name=my_function 'h/help' 'n/name=' -- $argv
or return or return
If ``$argv`` is empty then there is nothing to parse and ``argparse`` returns zero to indicate success. If ``$argv`` is not empty then it is checked for flags ``-h``, ``--help``, ``-n`` and ``--name``. If they are found they are removed from the arguments and local variables called ``_flag_OPTION`` are set so the script can determine which options were seen. If ``$argv`` doesn't have any errors, like a missing mandatory value for an option, then ``argparse`` exits with a status of zero. Otherwise it writes appropriate error messages to stderr and exits with a status of one.
The ``or return`` means that the function returns ``argparse``'s status if it failed, so if it goes on ``argparse`` succeeded. If ``$argv`` is empty then there is nothing to parse and ``argparse`` returns zero to indicate success. If ``$argv`` is not empty then it is checked for flags ``-h``, ``--help``, ``-n`` and ``--name``. If they are found they are removed from the arguments and local variables are set so the script can determine which options were seen. Assuming ``$argv`` doesn't have any errors, such as a missing mandatory value for an option, then ``argparse`` exits with status zero. Otherwise it writes appropriate error messages to stderr and exits with a status of one.
The ``--`` argument is required. You do not have to include any arguments after the ``--`` but you must include the ``--``. For example, this is acceptable:: The ``--`` argument is required. You do not have to include any arguments after the ``--`` but you must include the ``--``. For example, this is acceptable:
::
set -l argv set -l argv
argparse 'h/help' 'n/name' -- $argv argparse 'h/help' 'n/name' -- $argv
But this is not::
But this is not:
::
set -l argv set -l argv
argparse 'h/help' 'n/name' $argv argparse 'h/help' 'n/name' $argv
The first ``--`` seen is what allows the ``argparse`` command to reliably separate the option specifications and options to ``argparse`` itself (like ``--ignore-unknown``) from the command arguments, so it is required.
.. _cmd-argparse-option-specification: The first ``--`` seen is what allows the ``argparse`` command to reliably separate the option specifications from the command arguments.
Option Specifications Option Specifications
--------------------- ---------------------
Each option specification consists of: Each option specification is a string composed of
- An optional alphanumeric short flag character, followed by a ``/`` if the short flag can be used by someone invoking your command or, for backwards compatibility, a ``-`` if it should not be exposed as a valid short flag (in which case it will also not be exposed as a flag variable). - A short flag letter (which is mandatory). It must be an alphanumeric or "#". The "#" character is special and means that a flag of the form ``-123`` is valid. The short flag "#" must be followed by "-" (since the short name isn't otherwise valid since ``_flag_#`` is not a valid var name) and must be followed by a long flag name with no modifiers.
- An optional long flag name, which if not present the short flag can be used, and if that is also not present, an error is reported - A ``/`` if the short flag can be used by someone invoking your command else ``-`` if it should not be exposed as a valid short flag. If there is no long flag name these characters should be omitted. You can also specify a '#' to indicate the short and long flag names can be used and the value can be specified as an implicit int; i.e., a flag of the form ``-NNN``.
- Nothing if the flag is a boolean that takes no argument or is an integer flag, or - A long flag name which is optional. If not present then only the short flag letter can be used.
- **=** if it requires a value and only the last instance of the flag is saved, or - Nothing if the flag is a boolean that takes no argument or is an implicit int flag, else
- **=?** if it takes an optional value and only the last instance of the flag is saved, or - ``=`` if it requires a value and only the last instance of the flag is saved, else
- **=+** if it requires a value and each instance of the flag is saved. - ``=?`` it takes an optional value and only the last instance of the flag is saved, else
- Optionally a ``!`` followed by fish script to validate the value. Typically this will be a function to run. If the exit status is zero the value for the flag is valid. If non-zero the value is invalid. Any error messages should be written to stdout (not stderr). See the section on :ref:`Flag Value Validation <flag-value-validation>` for more information. - ``=+`` if it requires a value and each instance of the flag is saved.
- Optionally a ``!`` followed by fish script to validate the value. Typically this will be a function to run. If the exit status is zero the value for the flag is valid. If non-zero the value is invalid. Any error messages should be written to stdout (not stderr). See the section on `Flag Value Validation <#flag-value-validation>`__ for more information.
See the :ref:`fish_opt <cmd-fish_opt>` command for a friendlier but more verbose way to create option specifications. See the :ref:`fish_opt <cmd-fish_opt>` command for a friendlier but more verbose way to create option specifications.
If a flag is not seen when parsing the arguments then the corresponding _flag_X var(s) will not be set. In the following examples if a flag is not seen when parsing the arguments then the corresponding _flag_X var(s) will not be set.
Integer flag
------------
Sometimes commands take numbers directly as options, like ``foo -55``. To allow this one option spec can have the ``#`` modifier so that any integer will be understood as this flag, and the last number will be given as its value (as if ``=`` was used).
The ``#`` must follow the short flag letter (if any), and other modifiers like ``=`` are not allowed, except for ``-`` (for backwards compatibility)::
m#maximum
This does not read numbers given as ``+NNN``, only those that look like flags - ``-NNN``.
Note: Optional arguments Note: Optional arguments
------------------------ ------------------------
An option defined with ``=?`` can take optional arguments. Optional arguments have to be *directly attached* to the option they belong to. An option defined with ``=?`` can take optional arguments. Optional arguments have to be *directly attached* to the option they belong to.
That means the argument will only be used for the option if you use it like:: That means you can only call::
cmd --flag=value cmd --flag=value
# or # or
cmd -fvalue cmd -fvalue
but not if used like:: but not::
cmd --flag value cmd --flag value
# "value" here will be used as a positional argument # "value" here will be used as a positional argument and "--flag" won't have an argument.
# and "--flag" won't have an argument.
If this weren't the case, using an option without an optional argument would be difficult if you also wanted to use positional arguments. If this weren't the case, using an option without an optional argument would be difficult if you also wanted to use positional arguments.
For example:: For example::
grep --color auto grep --color auto
# Here "auto" will be used as the search string, # Here "auto" will be used as the search string, "color" will not have an argument and will fall back to the default
# "color" will not have an argument and will fall back to the default,
# which also *happens to be* auto.
grep --color always
# Here grep will still only use color "auto"matically
# and search for the string "always".
This isn't specific to argparse but common to all things using ``getopt(3)`` (if they have optional arguments at all). That ``grep`` example is how GNU grep actually behaves. This isn't specific to argparse but common to all things using ``getopt(3)`` (if they have optional arguments at all).
.. _flag-value-validation:
Flag Value Validation Flag Value Validation
--------------------- ---------------------
@@ -165,45 +148,28 @@ Fish ships with a ``_validate_int`` function that accepts a ``--min`` and ``--ma
Example OPTION_SPECs Example OPTION_SPECs
-------------------- --------------------
Some *OPTION_SPEC* examples: Some OPTION_SPEC examples:
- ``h/help`` means that both ``-h`` and ``--help`` are valid. The flag is a boolean and can be used more than once. If either flag is used then ``_flag_h`` and ``_flag_help`` will be set to the count of how many times either flag was seen. - ``h/help`` means that both ``-h`` and ``--help`` are valid. The flag is a boolean and can be used more than once. If either flag is used then ``_flag_h`` and ``_flag_help`` will be set to the count of how many times either flag was seen.
- ``help`` means that only ``--help`` is valid. The flag is a boolean and can be used more than once. If it is used then ``_flag_help`` will be set to the count of how many times the long flag was seen. Also ``h-help`` (with an arbitrary short letter) for backwards compatibility. - ``h-help`` means that only ``--help`` is valid. The flag is a boolean and can be used more than once. If the long flag is used then ``_flag_h`` and ``_flag_help`` will be set to the count of how many times the long flag was seen.
- ``longonly=`` is a flag ``--longonly`` that requires an option, there is no short flag or even short flag variable.
- ``n/name=`` means that both ``-n`` and ``--name`` are valid. It requires a value and can be used at most once. If the flag is seen then ``_flag_n`` and ``_flag_name`` will be set with the single mandatory value associated with the flag. - ``n/name=`` means that both ``-n`` and ``--name`` are valid. It requires a value and can be used at most once. If the flag is seen then ``_flag_n`` and ``_flag_name`` will be set with the single mandatory value associated with the flag.
- ``n/name=?`` means that both ``-n`` and ``--name`` are valid. It accepts an optional value and can be used at most once. If the flag is seen then ``_flag_n`` and ``_flag_name`` will be set with the value associated with the flag if one was provided else it will be set with no values. - ``n/name=?`` means that both ``-n`` and ``--name`` are valid. It accepts an optional value and can be used at most once. If the flag is seen then ``_flag_n`` and ``_flag_name`` will be set with the value associated with the flag if one was provided else it will be set with no values.
- ``name=+`` means that only ``--name`` is valid. It requires a value and can be used more than once. If the flag is seen then ``_flag_name`` will be set with the values associated with each occurrence. - ``n-name=+`` means that only ``--name`` is valid. It requires a value and can be used more than once. If the flag is seen then ``_flag_n`` and ``_flag_name`` will be set with the values associated with each occurrence of the flag.
- ``x`` means that only ``-x`` is valid. It is a boolean that can be used more than once. If it is seen then ``_flag_x`` will be set to the count of how many times the flag was seen. - ``x`` means that only ``-x`` is valid. It is a boolean that can be used more than once. If it is seen then ``_flag_x`` will be set to the count of how many times the flag was seen.
- ``x=``, ``x=?``, and ``x=+`` are similar to the n/name examples above but there is no long flag alternative to the short flag ``-x``. - ``x=``, ``x=?``, and ``x=+`` are similar to the n/name examples above but there is no long flag alternative to the short flag ``-x``.
- ``#max`` (or ``#-max``) means that flags matching the regex "^--?\\d+$" are valid. When seen they are assigned to the variable ``_flag_max``. This allows any valid positive or negative integer to be specified by prefixing it with a single "-". Many commands support this idiom. For example ``head -3 /a/file`` to emit only the first three lines of /a/file. - ``x-`` is not valid since there is no long flag name and therefore the short flag, ``-x``, has to be usable.
- ``n#max`` means that flags matching the regex "^--?\\d+$" are valid. When seen they are assigned to the variables ``_flag_n`` and ``_flag_max``. This allows any valid positive or negative integer to be specified by prefixing it with a single "-". Many commands support this idiom. For example ``head -3 /a/file`` to emit only the first three lines of /a/file. You can also specify the value using either flag: ``-n NNN`` or ``--max NNN`` in this example. - ``#-max`` means that flags matching the regex "^--?\d+$" are valid. When seen they are assigned to the variable ``_flag_max``. This allows any valid positive or negative integer to be specified by prefixing it with a single "-". Many commands support this idiom. For example ``head -3 /a/file`` to emit only the first three lines of /a/file.
- ``#longonly`` causes the last integer option to be stored in ``_flag_longonly``. - ``n#max`` means that flags matching the regex "^--?\d+$" are valid. When seen they are assigned to the variables ``_flag_n`` and ``_flag_max``. This allows any valid positive or negative integer to be specified by prefixing it with a single "-". Many commands support this idiom. For example ``head -3 /a/file`` to emit only the first three lines of /a/file. You can also specify the value using either flag: ``-n NNN`` or ``--max NNN`` in this example.
After parsing the arguments the ``argv`` variable is set with local scope to any values not already consumed during flag processing. If there are no unbound values the variable is set but ``count $argv`` will be zero. After parsing the arguments the ``argv`` var is set with local scope to any values not already consumed during flag processing. If there are not unbound values the var is set but ``count $argv`` will be zero.
If an error occurs during argparse processing it will exit with a non-zero status and print error messages to stderr. If an error occurs during argparse processing it will exit with a non-zero status and print error messages to stderr.
Limitations
-----------
One limitation with **--ignore-unknown** is that, if an unknown option is given in a group with known options, the entire group will be kept in $argv. ``argparse`` will not do any permutations here.
For instance::
argparse --ignore-unknown h -- -ho
echo $_flag_h # is -h, because -h was given
echo $argv # is still -ho
This limitation may be lifted in future.
Additionally, it can only parse known options up to the first unknown option in the group - the unknown option could take options, so it isn't clear what any character after an unknown option means.

View File

@@ -6,28 +6,30 @@ begin - start a new block of code
Synopsis Synopsis
-------- --------
.. synopsis:: ::
begin; [COMMANDS...;] end
begin; [COMMANDS ...]; end
Description Description
----------- -----------
``begin`` is used to create a new block of code. ``begin`` is used to create a new block of code.
A block allows the introduction of a new :ref:`variable scope <variables-scope>`, redirection of the input or output of a set of commands as a group, or to specify precedence when using the conditional commands like ``and``. A block allows the introduction of a new variable scope, redirection of the input or output of a set of commands as a group, or to specify precedence when using the conditional commands like ``and``.
The block is unconditionally executed. ``begin; ...; end`` is equivalent to ``if true; ...; end``. The block is unconditionally executed. ``begin; ...; end`` is equivalent to ``if true; ...; end``.
``begin`` does not change the current exit status itself. After the block has completed, ``$status`` will be set to the status returned by the most recent command. ``begin`` does not change the current exit status itself. After the block has completed, ``$status`` will be set to the status returned by the most recent command.
The **-h** or **--help** option displays help about using this command.
Example Example
------- -------
The following code sets a number of variables inside of a block scope. Since the variables are set inside the block and have local scope, they will be automatically deleted when the block ends. The following code sets a number of variables inside of a block scope. Since the variables are set inside the block and have local scope, they will be automatically deleted when the block ends.
:: ::
begin begin
@@ -43,6 +45,8 @@ The following code sets a number of variables inside of a block scope. Since the
In the following code, all output is redirected to the file out.html. In the following code, all output is redirected to the file out.html.
:: ::
begin begin
@@ -53,3 +57,4 @@ In the following code, all output is redirected to the file out.html.
end end
... ...
end > out.html end > out.html

View File

@@ -6,33 +6,27 @@ bg - send jobs to background
Synopsis Synopsis
-------- --------
.. synopsis:: ::
bg [PID ...] bg [PID...]
Description Description
----------- -----------
``bg`` sends :ref:`jobs <syntax-job-control>` to the background, resuming them if they are stopped. ``bg`` sends :ref:`jobs <syntax-job-control>` to the background, resuming them if they are stopped.
A background job is executed simultaneously with fish, and does not have access to the keyboard. If no job is specified, the last job to be used is put in the background. If ``PID`` is specified, the jobs containing the specified process IDs are put in the background. A background job is executed simultaneously with fish, and does not have access to the keyboard. If no job is specified, the last job to be used is put in the background. If PID is specified, the jobs with the specified process group IDs are put in the background.
For compatibility with other shells, job expansion syntax is supported for ``bg``. A PID of the format ``%1`` will be interpreted as the PID of job 1. Job numbers can be seen in the output of :ref:`jobs <cmd-jobs>`. When at least one of the arguments isn't a valid job specifier (i.e. PID),
When at least one of the arguments isn't a valid job specifier,
``bg`` will print an error without backgrounding anything. ``bg`` will print an error without backgrounding anything.
When all arguments are valid job specifiers, ``bg`` will background all matching jobs that exist. When all arguments are valid job specifiers, bg will background all matching jobs that exist.
The **-h** or **--help** option displays help about using this command.
Example Example
------- -------
``bg 123 456 789`` will background the jobs that contain processes 123, 456 and 789. ``bg 123 456 789`` will background 123, 456 and 789.
If only 123 and 789 exist, it will still background them and print an error about 456. If only 123 and 789 exist, it will still background them and print an error about 456.
``bg 123 banana`` or ``bg banana 123`` will complain that "banana" is not a valid job specifier. ``bg 123 banana`` or ``bg banana 123`` will complain that "banana" is not a valid job specifier.
``bg %1`` will background job 1.

View File

@@ -2,17 +2,18 @@
bind - handle fish key bindings bind - handle fish key bindings
=============================== ===============================
Synopsis Synopsis
-------- --------
.. synopsis:: ::
bind [(-M | --mode) MODE] [(-m | --sets-mode) NEW_MODE] [--preset | --user] [-s | --silent] [-k | --key] SEQUENCE COMMAND ... bind [(-M | --mode) MODE] [(-m | --sets-mode) NEW_MODE] [--preset | --user] [(-s | --silent)] [(-k | --key)] SEQUENCE COMMAND [COMMAND...]
bind [(-M | --mode) MODE] [-k | --key] [--preset] [--user] SEQUENCE bind [(-M | --mode) MODE] [(-k | --key)] [--preset] [--user] SEQUENCE
bind (-K | --key-names) [-a | --all] [--preset] [--user] bind (-K | --key-names) [(-a | --all)] [--preset] [--user]
bind (-f | --function-names) bind (-f | --function-names)
bind (-L | --list-modes) bind (-L | --list-modes)
bind (-e | --erase) [(-M | --mode) MODE] [--preset] [--user] [-a | --all] | [-k | --key] SEQUENCE ... bind (-e | --erase) [(-M | --mode) MODE] [--preset] [--user] (-a | --all | [(-k | --key)] SEQUENCE [SEQUENCE...])
Description Description
----------- -----------
@@ -27,11 +28,9 @@ The generic key binding that matches if no other binding does can be set by spec
If the ``-k`` switch is used, the name of a key (such as 'down', 'up' or 'backspace') is used instead of a sequence. The names used are the same as the corresponding curses variables, but without the 'key\_' prefix. (See ``terminfo(5)`` for more information, or use ``bind --key-names`` for a list of all available named keys). Normally this will print an error if the current ``$TERM`` entry doesn't have a given key, unless the ``-s`` switch is given. If the ``-k`` switch is used, the name of a key (such as 'down', 'up' or 'backspace') is used instead of a sequence. The names used are the same as the corresponding curses variables, but without the 'key\_' prefix. (See ``terminfo(5)`` for more information, or use ``bind --key-names`` for a list of all available named keys). Normally this will print an error if the current ``$TERM`` entry doesn't have a given key, unless the ``-s`` switch is given.
To find out what sequence a key combination sends, you can use :ref:`fish_key_reader <cmd-fish_key_reader>`.
``COMMAND`` can be any fish command, but it can also be one of a set of special input functions. These include functions for moving the cursor, operating on the kill-ring, performing tab completion, etc. Use ``bind --function-names`` for a complete list of these input functions. ``COMMAND`` can be any fish command, but it can also be one of a set of special input functions. These include functions for moving the cursor, operating on the kill-ring, performing tab completion, etc. Use ``bind --function-names`` for a complete list of these input functions.
When ``COMMAND`` is a shellscript command, it is a good practice to put the actual code into a :ref:`function <syntax-function>` and simply 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. When ``COMMAND`` is a shellscript command, it is a good practice to put the actual code into a `function <#function>`__ and simply 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 a script produces output, it should finish by calling ``commandline -f repaint`` to tell fish that a repaint is in order. If a script produces output, it should finish by calling ``commandline -f repaint`` to tell fish that a repaint is in order.
@@ -39,7 +38,7 @@ Note that special input functions cannot be combined with ordinary shell script
If no ``SEQUENCE`` is provided, all bindings (or just the bindings in the given ``MODE``) are printed. If ``SEQUENCE`` is provided but no ``COMMAND``, just the binding matching that sequence is printed. If no ``SEQUENCE`` is provided, all bindings (or just the bindings in the given ``MODE``) are printed. If ``SEQUENCE`` is provided but no ``COMMAND``, just the binding matching that sequence is printed.
To save custom keybindings, put the ``bind`` statements into :ref:`config.fish <configuration>`. Alternatively, fish also automatically executes a function called ``fish_user_key_bindings`` if it exists. To save custom keybindings, put the ``bind`` statements into :ref:`config.fish <initialization>`. Alternatively, fish also automatically executes a function called ``fish_user_key_bindings`` if it exists.
Key bindings may use "modes", which mimics Vi's modal input behavior. The default mode is "default", and every bind applies to a single mode. The mode can be viewed/changed with the ``$fish_bind_mode`` variable. Key bindings may use "modes", which mimics Vi's modal input behavior. The default mode is "default", and every bind applies to a single mode. The mode can be viewed/changed with the ``$fish_bind_mode`` variable.
@@ -47,300 +46,179 @@ Options
------- -------
The following options are available: The following options are available:
**-k** or **--key** - ``-k`` or ``--key`` Specify a key name, such as 'left' or 'backspace' instead of a character sequence
Specify a key name, such as 'left' or 'backspace' instead of a character sequence
**-K** or **--key-names** - ``-K`` or ``--key-names`` Display a list of available key names. Specifying ``-a`` or ``--all`` includes keys that don't have a known mapping
Display a list of available key names. Specifying **-a** or **--all** includes keys that don't have a known mapping
**-f** or **--function-names** - ``-f`` or ``--function-names`` Display a list of available input functions
Display a list of available input functions
**-L** or **--list-modes** - ``-L`` or ``--list-modes`` Display a list of defined bind modes
Display a list of defined bind modes
**-M MODE** or **--mode** *MODE* - ``-M MODE`` or ``--mode MODE`` Specify a bind mode that the bind is used in. Defaults to "default"
Specify a bind mode that the bind is used in. Defaults to "default"
**-m NEW_MODE** or **--sets-mode** *NEW_MODE* - ``-m NEW_MODE`` or ``--sets-mode NEW_MODE`` Change the current mode to ``NEW_MODE`` after this binding is executed
Change the current mode to *NEW_MODE* after this binding is executed
**-e** or **--erase** - ``-e`` or ``--erase`` Erase the binding with the given sequence and mode instead of defining a new one. Multiple sequences can be specified with this flag. Specifying ``-a`` or ``--all`` with ``-M`` or ``--mode`` erases all binds in the given mode regardless of sequence. Specifying ``-a`` or ``--all`` without ``-M`` or ``--mode`` erases all binds in all modes regardless of sequence.
Erase the binding with the given sequence and mode instead of defining a new one.
Multiple sequences can be specified with this flag.
Specifying **-a** or **--all** with **-M** or **--mode** erases all binds in the given mode regardless of sequence.
Specifying **-a** or **--all** without **-M** or **--mode** erases all binds in all modes regardless of sequence.
**-a** or **--all** - ``-a`` or ``--all`` See ``--erase`` and ``--key-names``
See **--erase** and **--key-names**
**--preset** and **--user** - ``--preset`` and ``--user`` specify if bind should operate on user or preset bindings. User bindings take precedence over preset bindings when fish looks up mappings. By default, all ``bind`` invocations work on the "user" level except for listing, which will show both levels. All invocations except for inserting new bindings can operate on both levels at the same time (if both ``--preset`` and ``--user`` are given). ``--preset`` should only be used in full binding sets (like when working on ``fish_vi_key_bindings``).
Specify if bind should operate on user or preset bindings.
User bindings take precedence over preset bindings when fish looks up mappings.
By default, all ``bind`` invocations work on the "user" level except for listing, which will show both levels.
All invocations except for inserting new bindings can operate on both levels at the same time (if both **--preset** and **--user** are given).
**--preset** should only be used in full binding sets (like when working on ``fish_vi_key_bindings``).
**-h** or **--help**
Displays help about using this command.
Special input functions Special input functions
----------------------- -----------------------
The following special input functions are available: The following special input functions are available:
``and`` - ``and``, only execute the next function if the previous succeeded (note: only some functions report success)
only execute the next function if the previous succeeded (note: only some functions report success)
``accept-autosuggestion`` - ``accept-autosuggestion``, accept the current autosuggestion completely
accept the current autosuggestion
``backward-char`` - ``backward-char``, moves one character to the left
move one character to the left.
If the completion pager is active, select the previous completion instead.
``backward-bigword`` - ``backward-bigword``, move one whitespace-delimited word to the left
move one whitespace-delimited word to the left
``backward-delete-char`` - ``backward-delete-char``, deletes one character of input to the left of the cursor
deletes one character of input to the left of the cursor
``backward-kill-bigword`` - ``backward-kill-bigword``, move the whitespace-delimited word to the left of the cursor to the killring
move the whitespace-delimited word to the left of the cursor to the killring
``backward-kill-line`` - ``backward-kill-line``, move everything from the beginning of the line to the cursor to the killring
move everything from the beginning of the line to the cursor to the killring
``backward-kill-path-component`` - ``backward-kill-path-component``, move one path component to the left of the cursor to the killring. A path component is everything likely to belong to a path component, i.e. not any of the following: `/={,}'\":@ |;<>&`, plus newlines and tabs.
move one path component to the left of the cursor to the killring. A path component is everything likely to belong to a path component, i.e. not any of the following: `/={,}'\":@ |;<>&`, plus newlines and tabs.
``backward-kill-word`` - ``backward-kill-word``, move the word to the left of the cursor to the killring. The "word" here is everything up to punctuation or whitespace.
move the word to the left of the cursor to the killring. The "word" here is everything up to punctuation or whitespace.
``backward-word`` - ``backward-word``, move one word to the left
move one word to the left
``beginning-of-buffer`` - ``beginning-of-buffer``, moves to the beginning of the buffer, i.e. the start of the first line
moves to the beginning of the buffer, i.e. the start of the first line
``beginning-of-history`` - ``beginning-of-history``, move to the beginning of the history
move to the beginning of the history
``beginning-of-line`` - ``beginning-of-line``, move to the beginning of the line
move to the beginning of the line
``begin-selection`` - ``begin-selection``, start selecting text
start selecting text
``cancel`` - ``cancel``, cancel the current commandline and replace it with a new empty one
cancel the current commandline and replace it with a new empty one
``cancel-commandline`` - ``capitalize-word``, make the current word begin with a capital letter
cancel the current commandline and replace it with a new empty one, leaving the old one in place with a marker to show that it was cancelled
``capitalize-word`` - ``complete``, guess the remainder of the current token
make the current word begin with a capital letter
``complete`` - ``complete-and-search``, invoke the searchable pager on completion options (for convenience, this also moves backwards in the completion pager)
guess the remainder of the current token
``complete-and-search`` - ``delete-char``, delete one character to the right of the cursor
invoke the searchable pager on completion options (for convenience, this also moves backwards in the completion pager)
``delete-char`` - ``delete-or-exit``, deletes one character to the right of the cursor or exits the shell if the commandline is empty.
delete one character to the right of the cursor
``delete-or-exit`` - ``down-line``, move down one line
delete one character to the right of the cursor, or exit the shell if the commandline is empty
``down-line`` - ``downcase-word``, make the current word lowercase
move down one line
``downcase-word`` - ``end-of-buffer``, moves to the end of the buffer, i.e. the end of the first line
make the current word lowercase
``end-of-buffer`` - ``end-of-history``, move to the end of the history
moves to the end of the buffer, i.e. the end of the first line
``end-of-history`` - ``end-of-line``, move to the end of the line
move to the end of the history
``end-of-line`` - ``end-selection``, end selecting text
move to the end of the line
``end-selection`` - ``expand-abbr`` expands any abbreviation currently under the cursor
end selecting text
``expand-abbr`` - ``execute`` run the current commandline
expands any abbreviation currently under the cursor
``execute`` - ``force-repaint`` reexecute the prompt functions without coalescing
run the current commandline
``exit`` - ``forward-bigword``, move one whitespace-delimited word to the right
exit the shell
``forward-bigword`` - ``forward-char``, move one character to the right
move one whitespace-delimited word to the right
``forward-char`` - ``forward-word``, move one word to the right
move one character to the right; or if at the end of the commandline, accept the current autosuggestion.
If the completion pager is active, select the next completion instead.
``forward-single-char`` - ``history-search-backward``, search the history for the previous match
move one character to the right; or if at the end of the commandline, accept a single char from the current autosuggestion.
``forward-word`` - ``history-search-forward``, search the history for the next match
move one word to the right; or if at the end of the commandline, accept one word
from the current autosuggestion.
``history-search-backward`` - ``history-prefix-search-backward``, search the history for the previous prefix match
search the history for the previous match
``history-search-forward`` - ``history-prefix-search-forward``, search the history for the next prefix match
search the history for the next match
``history-prefix-search-backward`` - ``history-token-search-backward``, search the history for the previous matching argument
search the history for the previous prefix match
``history-prefix-search-forward`` - ``history-token-search-forward``, search the history for the next matching argument
search the history for the next prefix match
``history-token-search-backward`` - ``forward-jump`` and ``backward-jump``, read another character and jump to its next occurence after/before the cursor
search the history for the previous matching argument
``history-token-search-forward`` - ``forward-jump-till`` and ``backward-jump-till``, jump to right *before* the next occurence
search the history for the next matching argument
``forward-jump`` and ``backward-jump`` - ``repeat-jump`` and ``repeat-jump-reverse``, redo the last jump in the same/opposite direction
read another character and jump to its next occurence after/before the cursor
``forward-jump-till`` and ``backward-jump-till`` - ``kill-bigword``, move the next whitespace-delimited word to the killring
jump to right *before* the next occurence
``repeat-jump`` and ``repeat-jump-reverse`` - ``kill-line``, move everything from the cursor to the end of the line to the killring
redo the last jump in the same/opposite direction
``kill-bigword`` - ``kill-selection``, move the selected text to the killring
move the next whitespace-delimited word to the killring
``kill-line`` - ``kill-whole-line``, move the line to the killring
move everything from the cursor to the end of the line to the killring
``kill-selection`` - ``kill-word``, move the next word to the killring
move the selected text to the killring
``kill-whole-line`` - ``pager-toggle-search``, toggles the search field if the completions pager is visible.
move the line to the killring
``kill-word`` - ``repaint`` reexecutes the prompt functions and redraws the prompt. Multiple successive repaints are coalesced.
move the next word to the killring
``nextd-or-forward-word`` - ``repaint-mode`` reexecutes the :ref:`fish_mode_prompt <cmd-fish_mode_prompt>` and redraws the prompt. This is useful for vi-mode. If no ``fish_mode_prompt`` exists, it acts like a normal repaint.
if the commandline is empty, then move forward in the directory history, otherwise move one word to the right;
or if at the end of the commandline, accept one word from the current autosuggestion.
``or`` - ``self-insert``, inserts the matching sequence into the command line
only execute the next function if the previous succeeded (note: only some functions report success)
``pager-toggle-search`` - ``self-insert-notfirst``, inserts the matching sequence into the command line, unless the cursor is at the beginning
toggles the search field if the completions pager is visible.
``prevd-or-backward-word`` - ``suppress-autosuggestion``, remove the current autosuggestion
if the commandline is empty, then move backward in the directory history, otherwise move one word to the left
``repaint`` - ``swap-selection-start-stop``, go to the other end of the highlighted text without changing the selection
reexecutes the prompt functions and redraws the prompt (also ``force-repaint`` for backwards-compatibility)
``repaint-mode`` - ``transpose-chars``, transpose two characters to the left of the cursor
reexecutes the :ref:`fish_mode_prompt <cmd-fish_mode_prompt>` and redraws the prompt. This is useful for vi-mode. If no ``fish_mode_prompt`` exists or it prints nothing, it acts like a normal repaint.
``self-insert`` - ``transpose-words``, transpose two words to the left of the cursor
inserts the matching sequence into the command line
``self-insert-notfirst`` - ``up-line``, move up one line
inserts the matching sequence into the command line, unless the cursor is at the beginning
``suppress-autosuggestion`` - ``undo`` and ``redo``, revert or redo the most recent edits on the command line
remove the current autosuggestion. Returns true if there was a suggestion to remove.
``swap-selection-start-stop`` - ``upcase-word``, make the current word uppercase
go to the other end of the highlighted text without changing the selection
``transpose-chars`` - ``yank``, insert the latest entry of the killring into the buffer
transpose two characters to the left of the cursor
``transpose-words`` - ``yank-pop``, rotate to the previous entry of the killring
transpose two words to the left of the cursor
``togglecase-char``
toggle the capitalisation (case) of the character under the cursor
``togglecase-selection``
toggle the capitalisation (case) of the selection
``insert-line-under``
add a new line under the current line
``insert-line-over``
add a new line over the current line
``up-line``
move up one line
``undo`` and ``redo``
revert or redo the most recent edits on the command line
``upcase-word``
make the current word uppercase
``yank``
insert the latest entry of the killring into the buffer
``yank-pop``
rotate to the previous entry of the killring
Additional functions
--------------------
The following functions are included as normal functions, but are particularly useful for input editing:
``up-or-search`` and ``down-or-search``
move the cursor or search the history depending on the cursor position and current mode
``edit_command_buffer``
open the visual editor (controlled by the :envvar:`VISUAL` or :envvar:`EDITOR` environment variables) with the current command-line contents
``fish_clipboard_copy``
copy the current selection to the system clipboard
``fish_clipboard_paste``
paste the current selection from the system clipboard before the cursor
``fish_commandline_append``
append the argument to the command-line. If the command-line already ends with the argument, this removes the suffix instead. Starts with the last command from history if the command-line is empty.
``fish_commandline_prepend``
prepend the argument to the command-line. If the command-line already starts with the argument, this removes the prefix instead. Starts with the last command from history if the command-line is empty.
Examples Examples
-------- --------
Exit the shell when :kbd:`Control`\ +\ :kbd:`D` is pressed:: ::
bind \cd 'exit' bind \cd 'exit'
Perform a history search when :kbd:`Page Up` is pressed:: Causes ``fish`` to exit when :kbd:`Control`\ +\ :kbd:`D` is pressed.
::
bind -k ppage history-search-backward bind -k ppage history-search-backward
Turn on :ref:`Vi key bindings <vi-mode>` and rebind :kbd:`Control`\ +\ :kbd:`C` to clear the input line:: Performs a history search when the :kbd:`Page Up` key is pressed.
::
set -g fish_key_bindings fish_vi_key_bindings set -g fish_key_bindings fish_vi_key_bindings
bind -M insert \cc kill-whole-line repaint bind -M insert \cc kill-whole-line force-repaint
Launch ``git diff`` and repaint the commandline afterwards when :kbd:`Control`\ +\ :kbd:`G` is pressed:: Turns on Vi key bindings and rebinds :kbd:`Control`\ +\ :kbd:`C` to clear the input line.
::
bind \cg 'git diff; commandline -f repaint' bind \cg 'git diff; commandline -f repaint'
Causes :kbd:`Control`\ +\ :kbd:`G` to launch ``git diff`` and repaint the commandline afterwards.
.. _cmd-bind-termlimits: .. _cmd-bind-termlimits:
Terminal Limitations Terminal Limitations
@@ -350,10 +228,10 @@ Unix terminals, like the ones fish operates in, are at heart 70s technology. The
For instance, the control key modifies a character by setting the top three bits to 0. This means: For instance, the control key modifies a character by setting the top three bits to 0. This means:
- Many characters + control are indistinguishable from other keys. :kbd:`Control`\ +\ :kbd:`I` *is* tab, :kbd:`Control`\ +\ :kbd:`J` *is* newline (``\n``). - Many characters + control are indistinguishable from other keys. :kbd:`Control`\ +\ :kbd:`I` *is* tab, :kbd:`Control`\ +\ :kbd:`J` *is* newline (`\n`).
- Control and shift don't work simultaneously - Control and shift don't work simultaneously
Other keys don't have a direct encoding, and are sent as escape sequences. For example :kbd:`→` (Right) often sends ``\e\[C``. These can differ from terminal to terminal, and the mapping is typically available in `terminfo(5)`. Sometimes however a terminal identifies as e.g. ``xterm-256color`` for compatibility, but then implements xterm's sequences incorrectly. Other keys don't have a direct encoding, and are sent as escape sequences. For example :kbd:`→` (Right) often sends `\e\[C`. These can differ from terminal to terminal, and the mapping is typically available in `terminfo(5)`. Sometimes however a terminal identifies as e.g. `xterm-256color` for compatibility, but then implements xterm's sequences incorrectly.
.. _cmd-bind-escape: .. _cmd-bind-escape:

View File

@@ -6,10 +6,10 @@ block - temporarily block delivery of events
Synopsis Synopsis
-------- --------
.. synopsis:: ::
block [OPTIONS...]
block [(--local | --global)]
block --erase
Description Description
----------- -----------
@@ -22,24 +22,18 @@ The block can be removed. Any events which triggered while the block was in plac
Event blocks should not be confused with code blocks, which are created with ``begin``, ``if``, ``while`` or ``for`` Event blocks should not be confused with code blocks, which are created with ``begin``, ``if``, ``while`` or ``for``
Without options, the ``block`` command acts with function scope. The following parameters are available:
The following options are available: - ``-l`` or ``--local`` Release the block automatically at the end of the current innermost code block scope
**-l** or **--local** - ``-g`` or ``--global`` Never automatically release the lock
Release the block automatically at the end of the current innermost code block scope.
**-g** or **--global** - ``-e`` or ``--erase`` Release global block
Never automatically release the lock.
**-e** or **--erase**
Release global block.
**-h** or **--help**
Displays help about using this command.
Example Example
------- -------
:: ::
# Create a function that listens for events # Create a function that listens for events
@@ -54,7 +48,8 @@ Example
block -e block -e
# 'foo fired' will now be printed # 'foo fired' will now be printed
Notes Notes
----- -----
Events are only received from the current fish process as there is no way to send events from one fish process to another (yet). Note that events are only received from the current fish process as there is no way to send events from one fish process to another.

View File

@@ -6,21 +6,19 @@ break - stop the current inner loop
Synopsis Synopsis
-------- --------
.. synopsis:: ::
LOOP_CONSTRUCT; [COMMANDS...] break; [COMMANDS...] end
LOOP_CONSTRUCT
[COMMANDS ...]
break
[COMMANDS ...]
end
Description Description
----------- -----------
``break`` halts a currently running loop (*LOOP_CONSTRUCT*), such as a :ref:`switch <cmd-switch>`, :ref:`for <cmd-for>` or :ref:`while <cmd-while>` loop. It is usually added inside of a conditional block such as an :ref:`if <cmd-if>` block. ``break`` halts a currently running loop, such as a :ref:`switch <cmd-switch>`, :ref:`for <cmd-for>` or :ref:`while <cmd-while>` loop. It is usually added inside of a conditional block such as an :ref:`if <cmd-if>` block.
There are no parameters for ``break``. There are no parameters for ``break``.
Example Example
------- -------
The following code searches all .c files for "smurf", and halts at the first occurrence. The following code searches all .c files for "smurf", and halts at the first occurrence.

View File

@@ -6,10 +6,11 @@ breakpoint - launch debug mode
Synopsis Synopsis
-------- --------
.. synopsis:: ::
breakpoint breakpoint
Description Description
----------- -----------

View File

@@ -6,31 +6,27 @@ builtin - run a builtin command
Synopsis Synopsis
-------- --------
.. synopsis:: ::
builtin [OPTIONS] BUILTINNAME builtin [OPTIONS...] BUILTINNAME
builtin --query BUILTINNAME ... builtin --query BUILTINNAMES...
builtin --names
Description Description
----------- -----------
``builtin`` forces the shell to use a builtin command named *BUILTIN*, rather than a function or external program. ``builtin`` forces the shell to use a builtin command, rather than a function or program.
The following options are available: The following parameters are available:
**-n** or **--names** - ``-n`` or ``--names`` List the names of all defined builtins
Lists the names of all defined builtins. - ``-q`` or ``--query`` tests if any of the specified builtins exists
**-q** or **--query** *BUILTIN*
Tests if any of the specified builtins exist.
**-h** or **--help**
Displays help about using this command.
Example Example
------- -------
:: ::
builtin jobs builtin jobs

View File

@@ -6,12 +6,9 @@ case - conditionally execute a block of commands
Synopsis Synopsis
-------- --------
.. synopsis:: ::
switch VALUE switch VALUE; [case [WILDCARD...]; [COMMANDS...]; ...] end
[case [GLOB ...]
[COMMAND ...]]
end
Description Description
----------- -----------

View File

@@ -6,7 +6,7 @@ cd - change directory
Synopsis Synopsis
-------- --------
.. synopsis:: ::
cd [DIRECTORY] cd [DIRECTORY]
@@ -14,22 +14,16 @@ Description
----------- -----------
``cd`` changes the current working directory. ``cd`` changes the current working directory.
If *DIRECTORY* is given, it will become the new directory. If no parameter is given, the :envvar:`HOME` environment variable will be used. If ``DIRECTORY`` is supplied, it will become the new directory. If no parameter is given, the contents of the ``HOME`` environment variable will be used.
If *DIRECTORY* is a relative path, all the paths in the :envvar:`CDPATH` will be tried as prefixes for it, in addition to :envvar:`PWD`. If ``DIRECTORY`` is a relative path, the paths found in the ``CDPATH`` list will be tried as prefixes for the specified path, in addition to $PWD.
It is recommended to keep **.** as the first element of :envvar:`CDPATH`, or :envvar:`PWD` will be tried last.
Fish will also try to change directory if given a command that looks like a directory (starting with **.**, **/** or **~**, or ending with **/**), without explicitly requiring **cd**. Note that the shell will attempt to change directory without requiring ``cd`` if the name of a directory is provided (starting with ``.``, ``/`` or ``~``, or ending with ``/``).
Fish also ships a wrapper function around the builtin **cd** that understands ``cd -`` as changing to the previous directory. Fish also ships a wrapper function around the builtin ``cd`` that understands ``cd -`` as changing to the previous directory. See also :ref:`prevd <cmd-prevd>`. This wrapper function maintains a history of the 25 most recently visited directories in the ``$dirprev`` and ``$dirnext`` global variables. If you make those universal variables your ``cd`` history is shared among all fish instances.
See also :ref:`prevd <cmd-prevd>`.
This wrapper function maintains a history of the 25 most recently visited directories in the ``$dirprev`` and ``$dirnext`` global variables.
If you make those universal variables your **cd** history is shared among all fish instances.
As a special case, ``cd .`` is equivalent to ``cd $PWD``, which is useful in cases where a mountpoint has been recycled or a directory has been removed and recreated. As a special case, ``cd .`` is equivalent to ``cd $PWD``, which is useful in cases where a mountpoint has been recycled or a directory has been removed and recreated.
The **--help** or **-h** option displays help about using this command, and does not change the directory.
Examples Examples
-------- --------

View File

@@ -6,21 +6,16 @@ cdh - change to a recently visited directory
Synopsis Synopsis
-------- --------
.. synopsis:: ::
cdh [DIRECTORY] cdh [ directory ]
Description Description
----------- -----------
``cdh`` with no arguments presents a list of :ref:`recently visited directories <directory-history>`. ``cdh`` with no arguments presents a list of :ref:`recently visited directories <directory-history>`. You can then select one of the entries by letter or number. You can also press :kbd:`Tab` to use the completion pager to select an item from the list. If you give it a single argument it is equivalent to ``cd directory``.
You can then select one of the entries by letter or number.
You can also press :kbd:`Tab` to use the completion pager to select an item from the list.
If you give it a single argument it is equivalent to ``cd DIRECTORY``.
Note that the ``cd`` command limits directory history to the 25 most recently visited directories. Note that the ``cd`` command limits directory history to the 25 most recently visited directories. The history is stored in the ``$dirprev`` and ``$dirnext`` variables which this command manipulates. If you make those universal variables your ``cd`` history is shared among all fish instances.
The history is stored in the :envvar:`dirprev` and :envvar:`$dirnext` variables, which this command manipulates.
If you make those universal variables, your ``cd`` history is shared among all fish instances.
See Also See Also
-------- --------

View File

@@ -6,36 +6,32 @@ command - run a program
Synopsis Synopsis
-------- --------
.. synopsis:: ::
command [OPTIONS] [COMMANDNAME [ARG ...]] command [OPTIONS] COMMANDNAME [ARGS...]
Description Description
----------- -----------
**command** forces the shell to execute the program *COMMANDNAME* and ignore any functions or builtins with the same name. ``command`` forces the shell to execute the program ``COMMANDNAME`` and ignore any functions or builtins with the same name.
The following options are available: The following options are available:
**-a** or **--all** - ``-a`` or ``--all`` returns all the external COMMANDNAMEs that are found in ``$PATH`` in the order they are found.
Prints all *COMMAND* found in :envvar:`PATH`, in the order found.
**-q** or **--query** - ``-q`` or ``--quiet``, silences the output and prints nothing, setting only the exit status. Implies ``--search``.
Silence output and print nothing, setting only exit status.
Implies **--search**.
For compatibility, this is also **--quiet** (deprecated).
**-v** (or **-s** or **--search**) - ``-s`` or ``--search`` returns the name of the external command that would be executed, or nothing if no file with the specified name could be found in the ``$PATH``.
Prints the external command that would be executed, or prints nothing if no file with the specified name could be found in :envvar:`PATH`.
**-h** or **--help** With the ``-s`` option, ``command`` treats every argument as a separate command to look up and sets the exit status to 0 if any of the specified commands were found, or 1 if no commands could be found. Additionally passing a ``-q`` or ``--quiet`` option prevents any paths from being printed, like ``type -q``, for testing only the exit status.
Displays help about using this command.
With the **-v** option, ``command`` treats every argument as a separate command to look up and sets the exit status to 0 if any of the specified commands were found, or 127 if no commands could be found. **--quiet** used with **-v** prevents commands being printed, like ``type -q``. For basic compatibility with POSIX ``command``, the ``-v`` flag is recognized as an alias for ``-s``.
Examples Examples
-------- --------
| ``command ls`` executes the ``ls`` program, even if an ``ls`` function also exists. ``command ls`` causes fish to execute the ``ls`` program, even if an ``ls`` function exists.
| ``command -s ls`` prints the path to the ``ls`` program.
| ``command -q git; and command git log`` runs ``git log`` only if ``git`` exists. ``command -s ls`` returns the path to the ``ls`` program.
``command -q git; and command git log`` runs ``git log`` only if ``git`` exists.

View File

@@ -6,7 +6,7 @@ commandline - set or get the current command line buffer
Synopsis Synopsis
-------- --------
.. synopsis:: ::
commandline [OPTIONS] [CMD] commandline [OPTIONS] [CMD]
@@ -17,81 +17,50 @@ Description
With no parameters, ``commandline`` returns the current value of the command line. With no parameters, ``commandline`` returns the current value of the command line.
With **CMD** specified, the command line buffer is erased and replaced with the contents of **CMD**. With ``CMD`` specified, the command line buffer is erased and replaced with the contents of ``CMD``.
The following options are available: The following options are available:
**-C** or **--cursor** - ``-C`` or ``--cursor`` set or get the current cursor position, not the contents of the buffer. If no argument is given, the current cursor position is printed, otherwise the argument is interpreted as the new cursor position.
Set or get the current cursor position, not the contents of the buffer.
If no argument is given, the current cursor position is printed, otherwise the argument is interpreted as the new cursor position.
If one of the options **-j**, **-p** or **-t** is given, the position is relative to the respective substring instead of the entire command line buffer.
**-f** or **--function** - ``-f`` or ``--function`` causes any additional arguments to be interpreted as input functions, and puts them into the queue, so that they will be read before any additional actual key presses are. This option cannot be combined with any other option. See :ref:`bind <cmd-bind>` for a list of input functions.
Causes any additional arguments to be interpreted as input functions, and puts them into the queue, so that they will be read before any additional actual key presses are.
This option cannot be combined with any other option.
See :ref:`bind <cmd-bind>` for a list of input functions.
**-h** or **--help**
Displays help about using this command.
The following options change the way ``commandline`` updates the command line buffer: The following options change the way ``commandline`` updates the command line buffer:
**-a** or **--append** - ``-a`` or ``--append`` do not remove the current commandline, append the specified string at the end of it
Do not remove the current commandline, append the specified string at the end of it.
**-i** or **--insert** - ``-i`` or ``--insert`` do not remove the current commandline, insert the specified string at the current cursor position
Do not remove the current commandline, insert the specified string at the current cursor position
**-r** or **--replace** - ``-r`` or ``--replace`` remove the current commandline and replace it with the specified string (default)
Remove the current commandline and replace it with the specified string (default)
The following options change what part of the commandline is printed or updated: The following options change what part of the commandline is printed or updated:
**-b** or **--current-buffer** - ``-b`` or ``--current-buffer`` select the entire buffer, including any displayed autosuggestion (default)
Select the entire commandline, not including any displayed autosuggestion (default).
**-j** or **--current-job** - ``-j`` or ``--current-job`` select the current job - a `job` here is one pipeline. It stops at logical operators or terminators (`;`, `&` or newlines).
Select the current job - a **job** here is one pipeline.
Stops at logical operators or terminators (**;**, **&**, and newlines).
**-p** or **--current-process** - ``-p`` or ``--current-process`` select the current process - a `process` here is one simple command. It stops at logical operators, terminators or pipes.
Select the current process - a **process** here is one command.
Stops at logical operators, terminators, and pipes.
**-s** or **--current-selection** - ``-s`` or ``--current-selection`` selects the current selection
Selects the current selection
**-t** or **--current-token** - ``-t`` or ``--current-token`` select the current token
Selects the current token
The following options change the way ``commandline`` prints the current commandline buffer: The following options change the way ``commandline`` prints the current commandline buffer:
**-c** or **--cut-at-cursor** - ``-c`` or ``--cut-at-cursor`` only print selection up until the current cursor position
Only print selection up until the current cursor position.
**-o** or **--tokenize** - ``-o`` or ``--tokenize`` tokenize the selection and print one string-type token per line
Tokenize the selection and print one string-type token per line.
If ``commandline`` is called during a call to complete a given string using ``complete -C STRING``, ``commandline`` will consider the specified string to be the current contents of the command line. If ``commandline`` is called during a call to complete a given string using ``complete -C STRING``, ``commandline`` will consider the specified string to be the current contents of the command line.
The following options output metadata about the commandline state: The following options output metadata about the commandline state:
**-L** or **--line** - ``-L`` or ``--line`` print the line that the cursor is on, with the topmost line starting at 1
Print the line that the cursor is on, with the topmost line starting at 1.
**-S** or **--search-mode** - ``-S`` or ``--search-mode`` evaluates to true if the commandline is performing a history search
Evaluates to true if the commandline is performing a history search.
**-P** or **--paging-mode** - ``-P`` or ``--paging-mode`` evaluates to true if the commandline is showing pager contents, such as tab completions
Evaluates to true if the commandline is showing pager contents, such as tab completions.
**--paging-full-mode**
Evaluates to true if the commandline is showing pager contents, such as tab completions and all lines are shown (no "<n> more rows" message).
**--is-valid**
Returns true when the commandline is syntactically valid and complete.
If it is, it would be executed when the ``execute`` bind function is called.
If the commandline is incomplete, return 2, if erroneus, return 1.
Example Example
------- -------
@@ -108,11 +77,11 @@ If the commandline contains
(with the cursor on the "o" of "flounder") (with the cursor on the "o" of "flounder")
The ``echo $flounder >&`` is the first process, ``less`` the second and ``and echo $catfish`` the third. The `echo $flounder >&` is the first process, `less` the second and `and echo $catfish` the third.
``echo $flounder >&2 | less`` is the first job, ``and echo $catfish`` the second. `echo $flounder >&2 | less` is the first job, `and echo $catfish` the second.
**$flounder** is the current token. `$flounder` is the current token.
More examples: More examples:

View File

@@ -6,109 +6,114 @@ complete - edit command specific tab-completions
Synopsis Synopsis
-------- --------
.. synopsis:: ::
complete ((-c | --command) | (-p | --path)) COMMAND [OPTIONS] complete ( -c | --command | -p | --path ) COMMAND
complete (-C | --do-complete) [--escape] STRING [( -c | --command | -p | --path ) COMMAND]...
[( -e | --erase )]
[( -s | --short-option ) SHORT_OPTION]...
[( -l | --long-option | -o | --old-option ) LONG_OPTION]...
[( -a | --arguments ) OPTION_ARGUMENTS]
[( -k | --keep-order )]
[( -f | --no-files )]
[( -F | --force-files )]
[( -r | --require-parameter )]
[( -x | --exclusive )]
[( -w | --wraps ) WRAPPED_COMMAND]...
[( -n | --condition ) CONDITION]
[( -d | --description ) DESCRIPTION]
complete ( -C [STRING] | --do-complete[=STRING] )
Description Description
----------- -----------
``complete`` defines, removes or lists completions for a command. For an introduction to specifying completions, see :ref:`Writing your own completions <completion-own>` in
For an introduction to writing your own completions, see :ref:`Writing your own completions <completion-own>` in
the fish manual. the fish manual.
The following options are available: - ``COMMAND`` is the name of the command for which to add a completion.
**-c** or **--command** *COMMAND* - ``SHORT_OPTION`` is a one character option for the command.
Specifies that *COMMAND* is the name of the command. If there is no **-c** or **-p**, one non-option argument will be used as the command.
**-p** or **--path** *COMMAND* - ``LONG_OPTION`` is a multi character option for the command.
Specifies that *COMMAND* is the absolute path of the command (optionally containing wildcards).
**-e** or **--erase** - ``OPTION_ARGUMENTS`` is parameter containing a space-separated list of possible option-arguments, which may contain command substitutions.
Deletes the specified completion.
**-s** or **--short-option** *SHORT_OPTION* - ``DESCRIPTION`` is a description of what the option and/or option arguments do.
Adds a short option to the completions list.
**-l** or **--long-option** *LONG_OPTION* - ``-c COMMAND`` or ``--command COMMAND`` specifies that ``COMMAND`` is the name of the command.
Adds a GNU style long option to the completions list.
**-o** or **--old-option** *LONG_OPTION* - ``-p COMMAND`` or ``--path COMMAND`` specifies that ``COMMAND`` is the absolute path of the program (optionally containing wildcards).
Adds an old style long option to the completions list (see below for details).
**-a** or **--arguments** *ARGUMENTS* - ``-e`` or ``--erase`` deletes the specified completion.
Adds the specified option arguments to the completions list.
**-k** or **--keep-order** - ``-s SHORT_OPTION`` or ``--short-option=SHORT_OPTION`` adds a short option to the completions list.
Keeps the order of *ARGUMENTS* instead of sorting alphabetically. Multiple ``complete`` calls with **-k** result in arguments of the later ones displayed first.
**-f** or **--no-files** - ``-l LONG_OPTION`` or ``--long-option=LONG_OPTION`` adds a GNU style long option to the completions list.
This completion may not be followed by a filename.
**-F** or **--force-files** - ``-o LONG_OPTION`` or ``--old-option=LONG_OPTION`` adds an old style long option to the completions list (See below for details).
This completion may be followed by a filename, even if another applicable ``complete`` specified **--no-files**.
**-r** or **--require-parameter** - ``-a OPTION_ARGUMENTS`` or ``--arguments=OPTION_ARGUMENTS`` adds the specified option arguments to the completions list.
This completion must have an option argument, i.e. may not be followed by another option.
**-x** or **--exclusive** - ``-k`` or ``--keep-order`` preserves the order of the ``OPTION_ARGUMENTS`` specified via ``-a`` or ``--arguments`` instead of sorting alphabetically. Multiple ``complete`` calls with ``-k`` result in arguments of the later ones displayed first.
Short for **-r** and **-f**.
**-w** or **--wraps** *WRAPPED_COMMAND* - ``-f`` or ``--no-files`` says that the options specified by this completion may not be followed by a filename.
Causes the specified command to inherit completions from *WRAPPED_COMMAND* (see below for details).
**-n** or **--condition** *CONDITION* - ``-F`` or ``--force-files`` says that the options specified by this completion may be followed by a filename, even if another applicable ``complete`` specified ``--no-files``.
This completion should only be used if the *CONDITION* (a shell command) returns 0. This makes it possible to specify completions that should only be used in some cases.
**-C** or **--do-complete** *STRING* - ``-r`` or ``--require-parameter`` says that the options specified by this completion must have an option argument, i.e. may not be followed by another option.
Makes ``complete`` try to find all possible completions for the specified string. If there is no *STRING*, the current commandline is used instead.
**--escape** - ``-x`` or ``--exclusive`` implies both ``-r`` and ``-f``.
When used with ``-C``, escape special characters in completions.
**-h** or **--help** - ``-w WRAPPED_COMMAND`` or ``--wraps=WRAPPED_COMMAND`` causes the specified command to inherit completions from the wrapped command (See below for details).
Displays help about using this command.
Command specific tab-completions in ``fish`` are based on the notion of options and arguments. An option is a parameter which begins with a hyphen, such as ``-h``, ``-help`` or ``--help``. Arguments are parameters that do not begin with a hyphen. Fish recognizes three styles of options, the same styles as the GNU getopt library. These styles are: - ``-n`` or ``--condition`` specifies a shell command that must return 0 if the completion is to be used. This makes it possible to specify completions that should only be used in some cases.
- Short options, like ``-a``. Short options are a single character long, are preceded by a single hyphen and can be grouped together (like ``-la``, which is equivalent to ``-l -a``). Option arguments may be specified by appending the option with the value (``-w32``), or, if ``--require-parameter`` is given, in the following parameter (``-w 32``). - ``-CSTRING`` or ``--do-complete=STRING`` makes complete try to find all possible completions for the specified string.
- Old style long options, like ``-Wall`` or ``-name``. Old style long options can be more than one character long, are preceded by a single hyphen and may not be grouped together. Option arguments are specified in the following parameter (``-ao null``) or after a ``=`` (``-ao=null``). - ``-C`` or ``--do-complete`` with no argument makes complete try to find all possible completions for the current command line buffer. If the shell is not in interactive mode, an error is returned.
- GNU style long options, like ``--colors``. GNU style long options can be more than one character long, are preceded by two hyphens, and can't be grouped together. Option arguments may be specified after a ``=`` (``--quoting-style=shell``), or, if ``--require-parameter`` is given, in the following parameter (``--quoting-style shell``). - ``-A`` and ``--authoritative`` no longer do anything and are silently ignored.
Multiple commands and paths can be given in one call to define the same completions for multiple commands. - ``-u`` and ``--unauthoritative`` no longer do anything and are silently ignored.
Multiple command switches and wrapped commands can also be given to define multiple completions in one call. Command specific tab-completions in ``fish`` are based on the notion of options and arguments. An option is a parameter which begins with a hyphen, such as ``-h``, ``-help`` or ``--help``. Arguments are parameters that do not begin with a hyphen. Fish recognizes three styles of options, the same styles as the GNU version of the getopt library. These styles are:
- Short options, like ``-a``. Short options are a single character long, are preceded by a single hyphen and may be grouped together (like ``-la``, which is equivalent to ``-l -a``). Option arguments may be specified in the following parameter (``-w 32``) or by appending the option with the value (``-w32``).
- Old style long options, like ``-Wall``. Old style long options can be more than one character long, are preceded by a single hyphen and may not be grouped together. Option arguments are specified in the following parameter (``-ao null``).
- GNU style long options, like ``--colors``. GNU style long options can be more than one character long, are preceded by two hyphens, and may not be grouped together. Option arguments may be specified in the following parameter (``--quoting-style shell``) or by appending the option with a ``=`` and the value (``--quoting-style=shell``). GNU style long options may be abbreviated so long as the abbreviation is unique (``--h``) is equivalent to ``--help`` if help is the only long option beginning with an 'h').
The options for specifying command name and command path may be used multiple times to define the same completions for multiple commands.
The options for specifying command switches and wrapped commands may be used multiple times to define multiple completions for the command(s) in a single call.
Invoking ``complete`` multiple times for the same command adds the new definitions on top of any existing completions defined for the command. Invoking ``complete`` multiple times for the same command adds the new definitions on top of any existing completions defined for the command.
When ``-a`` or ``--arguments`` is specified in conjunction with long, short, or old style options, the specified arguments are only completed as arguments for any of the specified options. If ``-a`` or ``--arguments`` is specified without any long, short, or old style options, the specified arguments are used when completing non-option arguments to the command (except when completing an option argument that was specified with ``-r`` or ``--require-parameter``). When ``-a`` or ``--arguments`` is specified in conjunction with long, short, or old style options, the specified arguments are only used as completions when attempting to complete an argument for any of the specified options. If ``-a`` or ``--arguments`` is specified without any long, short, or old style options, the specified arguments are used when completing any argument to the command (except when completing an option argument that was specified with ``-r`` or ``--require-parameter``).
Command substitutions found in ``ARGUMENTS`` should return a newline-separated list of arguments, and each argument may optionally have a tab character followed by the argument description. Description given this way override a description given with ``-d`` or ``--description``. Command substitutions found in ``OPTION_ARGUMENTS`` are not expected to return a space-separated list of arguments. Instead they must return a newline-separated list of arguments, and each argument may optionally have a tab character followed by the argument description. Any description provided in this way overrides a description given with ``-d`` or ``--description``.
Descriptions given with ``--description`` are also used to group options given with ``-s``, ``-o`` or ``-l``. Options with the same (non-empty) description will be listed as one candidate, and one of them will be picked. If the description is empty or no description was given this is skipped. The ``-w`` or ``--wraps`` options causes the specified command to inherit completions from another command. The inheriting command is said to "wrap" the inherited command. The wrapping command may have its own completions in addition to inherited ones. A command may wrap multiple commands, and wrapping is transitive: if A wraps B, and B wraps C, then A automatically inherits all of C's completions. Wrapping can be removed using the ``-e`` or ``--erase`` options. Note that wrapping only works for completions specified with ``-c`` or ``--command`` and are ignored when specifying completions with ``-p`` or ``--path``.
The ``-w`` or ``--wraps`` options causes the specified command to inherit completions from another command, "wrapping" the other command. The wrapping command can also have additional completions. A command can wrap multiple commands, and wrapping is transitive: if A wraps B, and B wraps C, then A automatically inherits all of C's completions. Wrapping can be removed using the ``-e`` or ``--erase`` options. Wrapping only works for completions specified with ``-c`` or ``--command`` and are ignored when specifying completions with ``-p`` or ``--path``. When erasing completions, it is possible to either erase all completions for a specific command by specifying ``complete -c COMMAND -e``, or by specifying a specific completion option to delete by specifying either a long, short or old style option.
When erasing completions, it is possible to either erase all completions for a specific command by specifying ``complete -c COMMAND -e``, or by specifying a specific completion option to delete.
When ``complete`` is called without anything that would define or erase completions (options, arguments, wrapping, ...), it shows matching completions instead. So ``complete`` without any arguments shows all loaded completions, ``complete -c foo`` shows all loaded completions for ``foo``. Since completions are :ref:`autoloaded <syntax-function-autoloading>`, you will have to trigger them first. Example
-------
The short style option ``-o`` for the ``gcc`` command requires that a file follows it. This can be done using writing:
Examples
--------
The short style option ``-o`` for the ``gcc`` command needs a file argument:
:: ::
complete -c gcc -s o -r complete -c gcc -s o -r
The short style option ``-d`` for the ``grep`` command requires one of ``read``, ``skip`` or ``recurse``: The short style option ``-d`` for the ``grep`` command requires that one of the strings ``read``, ``skip`` or ``recurse`` is used. This can be specified writing:
:: ::
@@ -117,6 +122,8 @@ The short style option ``-d`` for the ``grep`` command requires one of ``read``,
The ``su`` command takes any username as an argument. Usernames are given as the first colon-separated field in the file /etc/passwd. This can be specified as: The ``su`` command takes any username as an argument. Usernames are given as the first colon-separated field in the file /etc/passwd. This can be specified as:
:: ::
complete -x -c su -d "Username" -a "(cat /etc/passwd | cut -d : -f 1)" complete -x -c su -d "Username" -a "(cat /etc/passwd | cut -d : -f 1)"
@@ -126,6 +133,8 @@ The ``rpm`` command has several different modes. If the ``-e`` or ``--erase`` fl
This can be written as: This can be written as:
:: ::
complete -c rpm -n "__fish_contains_opt -s e erase" -l nodeps -d "Don't check dependencies" complete -c rpm -n "__fish_contains_opt -s e erase" -l nodeps -d "Don't check dependencies"
@@ -142,10 +151,5 @@ To implement an alias, use the ``-w`` or ``--wraps`` option:
complete -c hub -w git complete -c hub -w git
Now hub inherits all of the completions from git. Note this can also be specified in a function declaration (``function thing -w otherthing``). Now hub inherits all of the completions from git. Note this can also be specified in a function declaration.
::
complete -c git
Show all completions for ``git``.

View File

@@ -6,32 +6,27 @@ contains - test if a word is present in a list
Synopsis Synopsis
-------- --------
.. synopsis:: ::
contains [OPTIONS] KEY [VALUES ...] contains [OPTIONS] KEY [VALUES...]
Description Description
----------- -----------
``contains`` tests whether the set *VALUES* contains the string *KEY*. ``contains`` tests whether the set ``VALUES`` contains the string ``KEY``. If so, ``contains`` exits with status 0; if not, it exits with status 1.
If so, ``contains`` exits with code 0; if not, it exits with code 1.
The following options are available: The following options are available:
**-i** or **--index** - ``-i`` or ``--index`` print the word index
Print the index (number of the element in the set) of the first matching element.
**-h** or **--help** Note that, like GNU tools and most of fish's builtins, ``contains`` interprets all arguments starting with a ``-`` as options to contains, until it reaches an argument that is ``--`` (two dashes). See the examples below.
Displays help about using this command.
Note that ``contains`` interprets all arguments starting with a **-** as an option to ``contains``, until an **--** argument is reached.
See the examples below.
Example Example
------- -------
If *animals* is a list of animals, the following will test if *animals* contains "cat": If $animals is a list of animals, the following will test if it contains a cat:
:: ::
@@ -40,7 +35,9 @@ If *animals* is a list of animals, the following will test if *animals* contains
end end
This code will add some directories to :envvar:`PATH` if they aren't yet included: This code will add some directories to $PATH if they aren't yet included:
:: ::
@@ -51,7 +48,9 @@ This code will add some directories to :envvar:`PATH` if they aren't yet include
end end
While this will check if function ``hasargs`` is being ran with the **-q** option: While this will check if ``hasargs`` was run with the ``-q`` option:
:: ::
@@ -62,5 +61,4 @@ While this will check if function ``hasargs`` is being ran with the **-q** optio
end end
The **--** here stops ``contains`` from treating **-q** to an option to itself. The ``--`` here stops ``contains`` from treating ``-q`` to an option to itself. Instead it treats it as a normal string to check.
Instead it treats it as a normal string to check.

View File

@@ -6,9 +6,9 @@ continue - skip the remainder of the current iteration of the current inner loop
Synopsis Synopsis
-------- --------
.. synopsis:: ::
LOOP_CONSTRUCT; [COMMANDS ...;] continue; [COMMANDS ...;] end LOOP_CONSTRUCT; [COMMANDS...;] continue; [COMMANDS...;] end
Description Description
----------- -----------

View File

@@ -6,11 +6,11 @@ count - count the number of elements of a list
Synopsis Synopsis
-------- --------
.. synopsis:: ::
count STRING1 STRING2 ... count $VARIABLE
COMMAND | count COMMAND | count
count [...] < FILE count < FILE
Description Description
----------- -----------
@@ -34,8 +34,7 @@ Example
# Returns the number of directories in the users PATH variable. # Returns the number of directories in the users PATH variable.
count *.txt count *.txt
# Returns the number of files in the current working directory # Returns the number of files in the current working directory ending with the suffix '.txt'.
# ending with the suffix '.txt'.
git ls-files --others --exclude-standard | count git ls-files --others --exclude-standard | count
# Returns the number of untracked files in a git repository # Returns the number of untracked files in a git repository

View File

@@ -6,7 +6,7 @@ dirh - print directory history
Synopsis Synopsis
-------- --------
.. synopsis:: ::
dirh dirh

View File

@@ -6,26 +6,21 @@ dirs - print directory stack
Synopsis Synopsis
-------- --------
.. synopsis:: ::
dirs [-c] dirs
dirs -c
Description Description
----------- -----------
``dirs`` prints the current :ref:`directory stack <directory-stack>`, as created by :ref:`pushd <cmd-pushd>` and modified by :ref:`popd <cmd-popd>`. ``dirs`` prints the current :ref:`directory stack <directory-stack>`, as created by :ref:`pushd <cmd-pushd>` and modified by :ref:`popd <cmd-popd>`.
The following options are available: With "-c", it clears the directory stack instead.
**-c**: ``dirs`` does not accept any parameters.
Clear the directory stack instead of printing it.
**-h** or **--help**
Displays help about using this command.
``dirs`` does not accept any arguments.
See Also See Also
-------- --------
- the :ref:`cdh <cmd-cdh>` command, which provides a more intuitive way to navigate to recently visited directories. - the :ref:`cdh <cmd-cdh>` command which provides a more intuitive way to navigate to recently visited directories.

View File

@@ -6,9 +6,9 @@ disown - remove a process from the list of jobs
Synopsis Synopsis
-------- --------
.. synopsis:: ::
disown [PID ...] disown [ PID ... ]
Description Description
----------- -----------
@@ -23,8 +23,6 @@ If a job is stopped, it is sent a signal to continue running, and a warning is p
``disown`` returns 0 if all specified jobs were disowned successfully, and 1 if any problems were encountered. ``disown`` returns 0 if all specified jobs were disowned successfully, and 1 if any problems were encountered.
The **--help** or **-h** option displays help about using this command.
Example Example
------- -------

View File

@@ -6,30 +6,24 @@ echo - display a line of text
Synopsis Synopsis
-------- --------
.. synopsis:: ::
echo [OPTIONS] [STRING] echo [OPTIONS] [STRING]
Description Description
----------- -----------
``echo`` displays *STRING* of text. ``echo`` displays a string of text.
The following options are available: The following options are available:
- **-n** - ``-n``, Do not output a newline
Do not output a newline.
**-s** - ``-s``, Do not separate arguments with spaces
Do not separate arguments with spaces.
**-E** - ``-E``, Disable interpretation of backslash escapes (default)
Disable interpretation of backslash escapes (default).
**-e** - ``-e``, Enable interpretation of backslash escapes
Enable interpretation of backslash escapes.
Unlike other shells, this echo accepts ``--`` to signal the end of the options.
Escape Sequences Escape Sequences
---------------- ----------------
@@ -65,15 +59,15 @@ Example
:: ::
> echo 'Hello World' echo 'Hello World'
Hello World
> echo -e 'Top\nBottom' Print hello world to stdout
Top
Bottom
> echo -- -n ::
-n
echo -e 'Top\\nBottom'
Print Top and Bottom on separate lines, using an escape sequence
See Also See Also
-------- --------

View File

@@ -6,22 +6,22 @@ else - execute command if a condition is not met
Synopsis Synopsis
-------- --------
.. synopsis:: ::
if CONDITION; COMMANDS_TRUE ...; [else; COMMANDS_FALSE ...;] end if CONDITION; COMMANDS_TRUE...; [else; COMMANDS_FALSE...;] end
Description Description
----------- -----------
:ref:`if <cmd-if>` will execute the command *CONDITION**. :ref:`if <cmd-if>` will execute the command ``CONDITION``. If the condition's exit status is 0, the commands ``COMMANDS_TRUE`` will execute. If it is not 0 and ``else`` is given, ``COMMANDS_FALSE`` will be executed.
If the condition's exit status is 0, the commands *COMMANDS_TRUE* will execute.
If it is not 0 and **else** is given, *COMMANDS_FALSE* will be executed.
Example Example
------- -------
The following code tests whether a file *foo.txt* exists as a regular file. The following code tests whether a file ``foo.txt`` exists as a regular file.
:: ::

View File

@@ -6,16 +6,15 @@ emit - emit a generic event
Synopsis Synopsis
-------- --------
.. synopsis:: ::
emit EVENT_NAME [ARGUMENTS ...] emit EVENT_NAME [ARGUMENTS...]
Description Description
----------- -----------
``emit`` emits, or fires, an event. Events are delivered to, or caught by, special functions called :ref:`event handlers <event>`. The arguments are passed to the event handlers as function arguments. ``emit`` emits, or fires, an event. Events are delivered to, or caught by, special functions called :ref:`event handlers <event>`. The arguments are passed to the event handlers as function arguments.
The **--help** or **-h** option displays help about using this command.
Example Example
------- -------

View File

@@ -6,29 +6,23 @@ end - end a block of commands
Synopsis Synopsis
-------- --------
.. synopsis:: ::
begin begin; [COMMANDS...] end
[COMMANDS ...] function NAME [OPTIONS]; COMMANDS...; end
end if CONDITION; COMMANDS_TRUE...; [else; COMMANDS_FALSE...;] end
switch VALUE; [case [WILDCARD...]; [COMMANDS...]; ...] end
.. synopsis:: while CONDITION; COMMANDS...; end
for VARNAME in [VALUES...]; COMMANDS...; end
function NAME [OPTIONS]; COMMANDS ...; end
if CONDITION; COMMANDS_TRUE ...; [else; COMMANDS_FALSE ...;] end
switch VALUE; [case [WILDCARD ...]; [COMMANDS ...]; ...] end
while CONDITION; COMMANDS ...; end
for VARNAME in [VALUES ...]; COMMANDS ...; end
Description Description
----------- -----------
The **end** keyword ends a block of commands started by one of the following commands: ``end`` ends a block of commands started by one of the following commands:
- :ref:`begin <cmd-begin>` to start a block of commands - :ref:`begin <cmd-begin>` to start a block of commands
- :ref:`function <cmd-function>` to define a function - :ref:`function <cmd-function>` to define a function
- :ref:`if <cmd-if>`, :ref:`switch <cmd-switch>` to conditionally execute commands - :ref:`if <cmd-if>`, :ref:`switch <cmd-switch>` to conditionally execute commands
- :ref:`while <cmd-while>`, :ref:`for <cmd-for>` to perform commands multiple times - :ref:`while <cmd-while>`, :ref:`for <cmd-for>` to perform commands multiple times
The **end** keyword does not change the current exit status. The ``end`` command does not change the current exit status. Instead, the status after it will be the status returned by the most recent command.
Instead, the status after it will be the status returned by the most recent command.

Some files were not shown because too many files have changed in this diff Show More