mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-10 18:31:14 -03:00
Compare commits
40 Commits
Integratio
...
coverity_s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9da2f9c77 | ||
|
|
62b69532b1 | ||
|
|
2f1e8d9f8b | ||
|
|
64c8cee001 | ||
|
|
2ea6b8c128 | ||
|
|
ed844fa0ac | ||
|
|
b0bda695b5 | ||
|
|
e945a5f179 | ||
|
|
dfeccf2a1e | ||
|
|
593675e05e | ||
|
|
50a5460c17 | ||
|
|
172436f508 | ||
|
|
10a3eedcab | ||
|
|
53d8d9e0d9 | ||
|
|
642edbc434 | ||
|
|
d85bf9c0da | ||
|
|
37503f5f01 | ||
|
|
193dbe2a78 | ||
|
|
e95b9c16f0 | ||
|
|
d1bfea9ee5 | ||
|
|
c9c2cd069d | ||
|
|
c5409335ee | ||
|
|
db9259210d | ||
|
|
998b878dda | ||
|
|
32e2d36a7a | ||
|
|
37dc28f354 | ||
|
|
20ee1ce94b | ||
|
|
5c95da56a4 | ||
|
|
82325778a5 | ||
|
|
49d8e71e1f | ||
|
|
a9d1fb23da | ||
|
|
d8d194af63 | ||
|
|
85295488a6 | ||
|
|
7a8c5f53d5 | ||
|
|
bec4c374f5 | ||
|
|
d925862350 | ||
|
|
1f2a2de414 | ||
|
|
c21d880f34 | ||
|
|
e1dde5d7e1 | ||
|
|
66d7850b18 |
@@ -4,13 +4,12 @@ packages:
|
||||
- ninja
|
||||
- ncurses-dev
|
||||
- pcre2-dev
|
||||
- python3
|
||||
- py-pip
|
||||
- expect
|
||||
- python
|
||||
sources:
|
||||
- https://git.sr.ht/~faho/fish
|
||||
tasks:
|
||||
- build: |
|
||||
pip3 install pexpect
|
||||
cd fish
|
||||
mkdir build || :
|
||||
cd build
|
||||
@@ -22,4 +21,4 @@ tasks:
|
||||
ninja
|
||||
- test: |
|
||||
cd fish/build
|
||||
env ninja test
|
||||
env SHOW_INTERACTIVE_LOG=1 ninja test
|
||||
|
||||
@@ -2,8 +2,8 @@ image: archlinux
|
||||
packages:
|
||||
- cmake
|
||||
- ninja
|
||||
- expect
|
||||
- python
|
||||
- python-pexpect
|
||||
sources:
|
||||
- https://git.sr.ht/~faho/fish
|
||||
tasks:
|
||||
@@ -19,4 +19,4 @@ tasks:
|
||||
ninja
|
||||
- test: |
|
||||
cd fish/build
|
||||
env ninja test
|
||||
env SHOW_INTERACTIVE_LOG=1 ninja test
|
||||
|
||||
@@ -3,11 +3,11 @@ packages:
|
||||
- ncurses
|
||||
- gcc
|
||||
- gettext
|
||||
- expect
|
||||
- cmake
|
||||
- gmake
|
||||
- pcre2
|
||||
- python
|
||||
- py38-pexpect
|
||||
sources:
|
||||
- https://git.sr.ht/~faho/fish
|
||||
tasks:
|
||||
@@ -23,4 +23,4 @@ tasks:
|
||||
gmake -j2
|
||||
- test: |
|
||||
cd fish/build
|
||||
gmake test
|
||||
gmake test SHOW_INTERACTIVE_LOG=1
|
||||
|
||||
77
.cirrus.yml
77
.cirrus.yml
@@ -1,77 +0,0 @@
|
||||
env:
|
||||
CIRRUS_CLONE_DEPTH: 1
|
||||
CI: 1
|
||||
|
||||
linux_task:
|
||||
matrix:
|
||||
- name: alpine
|
||||
container: &step
|
||||
image: ghcr.io/fish-shell/fish-ci/alpine:latest
|
||||
memory: 4GB
|
||||
- name: centos7
|
||||
container:
|
||||
<<: *step
|
||||
image: ghcr.io/fish-shell/fish-ci/centos7:latest
|
||||
- name: centos8
|
||||
container:
|
||||
<<: *step
|
||||
image: ghcr.io/fish-shell/fish-ci/centos8:latest
|
||||
- name: focal-32bit
|
||||
container:
|
||||
<<: *step
|
||||
image: ghcr.io/fish-shell/fish-ci/focal-32bit:latest
|
||||
|
||||
tests_script:
|
||||
# cirrus at times gives us 32 procs and 2 GB of RAM
|
||||
# Unrestriced parallelism results in OOM
|
||||
- lscpu || true
|
||||
- (cat /proc/meminfo | grep MemTotal) || true
|
||||
- mkdir build && cd build
|
||||
- cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCTEST_PARALLEL_LEVEL=6 ..
|
||||
- ninja -j 6 fish fish_tests
|
||||
- ninja fish_run_tests
|
||||
|
||||
only_if: $CIRRUS_REPO_OWNER == 'fish-shell'
|
||||
|
||||
linux_arm_task:
|
||||
matrix:
|
||||
- name: focal-arm64
|
||||
arm_container:
|
||||
image: ghcr.io/fish-shell/fish-ci/focal-arm64
|
||||
only_if: $CIRRUS_REPO_OWNER == 'fish-shell'
|
||||
|
||||
tests_script:
|
||||
# cirrus at times gives us 32 procs and 2 GB of RAM
|
||||
# Unrestriced parallelism results in OOM
|
||||
- lscpu || true
|
||||
- (cat /proc/meminfo | grep MemTotal) || true
|
||||
- mkdir build && cd build
|
||||
- cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCTEST_PARALLEL_LEVEL=6 ..
|
||||
- ninja -j 6 fish fish_tests
|
||||
- file ./fish
|
||||
- ninja fish_run_tests
|
||||
|
||||
only_if: $CIRRUS_REPO_OWNER == 'fish-shell'
|
||||
|
||||
freebsd_task:
|
||||
matrix:
|
||||
- name: FreeBSD 13
|
||||
freebsd_instance:
|
||||
image: freebsd-13-2-release-amd64
|
||||
tests_script:
|
||||
- pkg install -y cmake devel/pcre2 devel/ninja misc/py-pexpect git
|
||||
# BSDs have the following behavior: root may open or access files even if
|
||||
# the mode bits would otherwise disallow it. For example root may open()
|
||||
# a file with write privileges even if the file has mode 400. This breaks
|
||||
# our tests for e.g. cd and path. So create a new unprivileged user to run tests.
|
||||
- pw user add -n fish-user -s /bin/csh -d /home/fish-user
|
||||
- mkdir -p /home/fish-user
|
||||
- chown -R fish-user /home/fish-user
|
||||
- mkdir build && cd build
|
||||
- chown -R fish-user ..
|
||||
- sudo -u fish-user -s whoami
|
||||
- sudo -u fish-user -s cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCTEST_PARALLEL_LEVEL=1 ..
|
||||
- sudo -u fish-user -s ninja -j 6 fish fish_tests
|
||||
- sudo -u fish-user -s ninja fish_run_tests
|
||||
|
||||
only_if: $CIRRUS_REPO_OWNER == 'fish-shell'
|
||||
@@ -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: ''
|
||||
HeaderFilterRegex: ''
|
||||
AnalyzeTemporaryDtors: false
|
||||
|
||||
@@ -10,6 +10,3 @@ varFuncNullUB
|
||||
unmatchedSuppression
|
||||
// Suppress this one because it reports assert(condition && "message"), which we use all over the place
|
||||
incorrectStringBooleanError
|
||||
|
||||
// This is of very little use and pops up *everywhere*.
|
||||
useStlAlgorithm
|
||||
@@ -20,9 +20,3 @@ indent_size = 2
|
||||
|
||||
[Dockerfile]
|
||||
indent_size = 2
|
||||
|
||||
[share/{completions,functions}/**.fish]
|
||||
max_line_length = none
|
||||
|
||||
[{COMMIT_EDITMSG,git-revise-todo}]
|
||||
max_line_length = 80
|
||||
|
||||
10
.gitattributes
vendored
10
.gitattributes
vendored
@@ -21,13 +21,11 @@
|
||||
/.github/* 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
|
||||
pcre2/** linguist-vendored
|
||||
/pcre2/* linguist-vendored
|
||||
angular.js linguist-vendored
|
||||
angular-*.js linguist-vendored
|
||||
doc_src/** linguist-documentation
|
||||
/doc_src/* linguist-documentation
|
||||
*.fish linguist-language=fish
|
||||
src/*.h linguist-language=c++
|
||||
src/builtins/*.h linguist-language=c++
|
||||
share/completions/*.fish linguist-documentation
|
||||
/tests/*.in linguist-language=fish
|
||||
|
||||
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -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.
|
||||
-->
|
||||
|
||||
**YOUR TEXT HERE**
|
||||
|
||||
17
.github/workflows/lockthreads.yml
vendored
17
.github/workflows/lockthreads.yml
vendored
@@ -2,24 +2,15 @@ name: 'Lock threads'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 18 * * 1'
|
||||
# │ │ │ │ │
|
||||
# min 0-59 ┘ │ │ │ └ weekday 0-6
|
||||
# hour 0-23 ┘ │ └ month 1-12
|
||||
# └ day 1-31
|
||||
permissions:
|
||||
contents: read
|
||||
- cron: '0 * * * *'
|
||||
|
||||
jobs:
|
||||
lock:
|
||||
permissions:
|
||||
issues: write # for dessant/lock-threads to lock issues
|
||||
pull-requests: write # for dessant/lock-threads to lock PRs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v2
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-lock-inactive-days: '365'
|
||||
pr-lock-inactive-days: '365'
|
||||
issue-exclude-labels: 'question, needs more info'
|
||||
issue-lock-inactive-days: '90'
|
||||
pr-lock-inactive-days: '90'
|
||||
issue-exclude-labels: 'question'
|
||||
|
||||
143
.github/workflows/main.yml
vendored
143
.github/workflows/main.yml
vendored
@@ -1,13 +1,10 @@
|
||||
name: make test
|
||||
name: C/C++ CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
CTEST_PARALLEL_LEVEL: "1"
|
||||
CMAKE_BUILD_PARALLEL_LEVEL: "4"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
ubuntu:
|
||||
@@ -18,14 +15,8 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt install gettext libncurses5-dev libpcre2-dev python3-pip tmux
|
||||
sudo pip3 install pexpect
|
||||
# Generate a locale that uses a comma as decimal separator.
|
||||
sudo locale-gen fr_FR.UTF-8
|
||||
sudo apt install expect gettext libncurses5-dev libpcre2-dev
|
||||
- name: cmake
|
||||
env:
|
||||
# Some warnings upgraded to errors to match Open Build Service platforms
|
||||
CXXFLAGS: "-Werror=address -Werror=return-type"
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
@@ -36,108 +27,22 @@ jobs:
|
||||
run: |
|
||||
make test
|
||||
|
||||
ubuntu-32bit-fetched-pcre2:
|
||||
# macos:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
# runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install gettext lib32ncurses5-dev python3-pip g++-multilib tmux
|
||||
sudo pip3 install pexpect
|
||||
- name: cmake
|
||||
env:
|
||||
CXXFLAGS: "-m32 -Werror=address -Werror=return-type"
|
||||
CFLAGS: "-m32"
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake -DFISH_USE_SYSTEM_PCRE2=OFF ..
|
||||
- name: make
|
||||
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 -DFISH_CI_SAN"
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
- name: make
|
||||
run: |
|
||||
make
|
||||
- name: make test
|
||||
env:
|
||||
FISH_CI_SAN: 1
|
||||
ASAN_OPTIONS: check_initialization_order=1:detect_stack_use_after_return=1:detect_leaks=1
|
||||
UBSAN_OPTIONS: print_stacktrace=1:report_error_type=1
|
||||
# use_tls=0 is a workaround for LSAN crashing with "Tracer caught signal 11" (SIGSEGV),
|
||||
# which seems to be an issue with TLS support in newer glibc versions under virtualized
|
||||
# environments. Follow https://github.com/google/sanitizers/issues/1342 and
|
||||
# https://github.com/google/sanitizers/issues/1409 to track this issue.
|
||||
LSAN_OPTIONS: verbosity=0:log_threads=0:use_tls=0
|
||||
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:
|
||||
FISH_CI_SAN: 1
|
||||
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
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - name: Install deps
|
||||
# run: |
|
||||
# brew install pcre2
|
||||
# - name: cmake
|
||||
# run: |
|
||||
# mkdir build && cd build
|
||||
# cmake ..
|
||||
# - name: make
|
||||
# run: |
|
||||
# make
|
||||
# - name: make test
|
||||
# run: |
|
||||
# make test
|
||||
|
||||
122
.travis.yml
Normal file
122
.travis.yml
Normal 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=
|
||||
12
BSDmakefile
12
BSDmakefile
@@ -20,22 +20,20 @@ _GENERATOR!=which ninja 2>/dev/null >/dev/null && echo Ninja || echo "Unix Makef
|
||||
GENERATOR?=$(_GENERATOR)
|
||||
|
||||
.if $(GENERATOR) == "Ninja"
|
||||
BUILDFILE=build.ninja
|
||||
BUILDFILE=build/build.ninja
|
||||
.else
|
||||
BUILDFILE=Makefile
|
||||
BUILDFILE=build/Makefile
|
||||
.endif
|
||||
|
||||
PREFIX?=/usr/local
|
||||
|
||||
.PHONY: build/fish
|
||||
build/fish: build/$(BUILDFILE)
|
||||
$(CMAKE) --build build
|
||||
|
||||
# Don't split the mkdir into its own rule because that would cause CMake to regenerate the 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):
|
||||
build:
|
||||
mkdir -p build
|
||||
|
||||
build/$(BUILDFILE): build
|
||||
cd build; $(CMAKE) .. -G "$(GENERATOR)" -DCMAKE_INSTALL_PREFIX="$(PREFIX)" -DCMAKE_EXPORT_COMPILE_COMMANDS=1
|
||||
|
||||
.PHONY: install
|
||||
|
||||
2955
CHANGELOG.rst
2955
CHANGELOG.rst
File diff suppressed because it is too large
Load Diff
128
CMakeLists.txt
128
CMakeLists.txt
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
|
||||
if(POLICY CMP0066)
|
||||
cmake_policy(SET CMP0066 OLD)
|
||||
@@ -16,56 +16,62 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(DEFAULT_BUILD_TYPE "RelWithDebInfo")
|
||||
|
||||
# Generate Xcode schemas (but not for tests).
|
||||
set(CMAKE_XCODE_GENERATE_SCHEME 1)
|
||||
# Use the default flags (#6296) but remove -DNDEBUG so that asserts remain enabled.
|
||||
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)
|
||||
message(STATUS "Setting build type to default '${DEFAULT_BUILD_TYPE}'")
|
||||
set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}")
|
||||
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.
|
||||
# Rationale in https://github.com/ninja-build/ninja/issues/814
|
||||
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 "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)))
|
||||
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()
|
||||
|
||||
# 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.
|
||||
# - 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)
|
||||
|
||||
if ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"))
|
||||
add_compile_options(-Wunused-template -Wunused-local-typedef -Wunused-macros)
|
||||
endif()
|
||||
# - 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
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra \
|
||||
-Wno-implicit-fallthrough \
|
||||
-Wno-comment \
|
||||
-Wno-address \
|
||||
-Wno-strict-aliasing \
|
||||
-Wno-redundant-move \
|
||||
")
|
||||
|
||||
# Disable exception handling.
|
||||
add_compile_options(-fno-exceptions)
|
||||
|
||||
# Undefine NDEBUG to keep assert() in release builds.
|
||||
add_definitions(-UNDEBUG)
|
||||
|
||||
# Enable large files on GNU.
|
||||
add_definitions(-D_LARGEFILE_SOURCE
|
||||
-D_LARGEFILE64_SOURCE
|
||||
-D_FILE_OFFSET_BITS=64
|
||||
-D_ATFILE_SOURCE)
|
||||
# Prefer the gold linker because it doesn't emit useless warnings about sys_nerr and _sys_errlist.
|
||||
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.
|
||||
source_group("CMake Rules" REGULAR_EXPRESSION "^$")
|
||||
|
||||
# Put source and header files at top level under targets.
|
||||
source_group("Source Files" REGULAR_EXPRESSION ".*\\.cpp")
|
||||
source_group("Header Files" REGULAR_EXPRESSION ".*\\.h")
|
||||
source_group("Builtins" "builtins/")
|
||||
source_group("Source Files" REGULAR_EXPRESSION "^$")
|
||||
source_group("Header Files" REGULAR_EXPRESSION "^$")
|
||||
source_group("Builtins" REGULAR_EXPRESSION "builtin_.*")
|
||||
|
||||
# Support folders.
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
@@ -89,38 +95,33 @@ if(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
endif()
|
||||
|
||||
# List of sources for builtin functions.
|
||||
set(FISH_BUILTIN_SRCS
|
||||
src/builtin.cpp src/builtins/abbr.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/path.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.
|
||||
# All objects that the system needs to build fish, except fish.cpp
|
||||
set(FISH_SRCS
|
||||
src/ast.cpp src/abbrs.cpp src/autoload.cpp src/color.cpp src/common.cpp src/complete.cpp
|
||||
src/env.cpp src/env_dispatch.cpp src/env_universal_common.cpp src/event.cpp
|
||||
src/exec.cpp src/expand.cpp src/fallback.cpp src/fd_monitor.cpp src/fish_version.cpp
|
||||
src/flog.cpp src/function.cpp src/future_feature_flags.cpp src/highlight.cpp
|
||||
src/history.cpp src/history_file.cpp src/input.cpp src/input_common.cpp
|
||||
src/io.cpp src/iothread.cpp src/job_group.cpp src/kill.cpp
|
||||
src/null_terminated_array.cpp src/operation_context.cpp src/output.cpp
|
||||
src/pager.cpp src/parse_execution.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/re.cpp src/reader.cpp src/redirection.cpp src/screen.cpp
|
||||
src/signal.cpp src/termsize.cpp src/timer.cpp src/tinyexpr.cpp
|
||||
src/tokenizer.cpp src/topic_monitor.cpp src/trace.cpp src/utf8.cpp src/util.cpp
|
||||
src/wait_handle.cpp src/wcstringutil.cpp src/wgetopt.cpp src/wildcard.cpp
|
||||
src/wutil.cpp src/fds.cpp
|
||||
src/autoload.cpp src/builtin.cpp src/builtin_bg.cpp src/builtin_bind.cpp
|
||||
src/builtin_block.cpp src/builtin_builtin.cpp src/builtin_cd.cpp
|
||||
src/builtin_command.cpp src/builtin_commandline.cpp
|
||||
src/builtin_complete.cpp src/builtin_contains.cpp src/builtin_disown.cpp
|
||||
src/builtin_echo.cpp src/builtin_emit.cpp src/builtin_exit.cpp
|
||||
src/builtin_fg.cpp src/builtin_function.cpp src/builtin_functions.cpp
|
||||
src/builtin_argparse.cpp src/builtin_history.cpp src/builtin_jobs.cpp
|
||||
src/builtin_math.cpp src/builtin_printf.cpp src/builtin_pwd.cpp
|
||||
src/builtin_random.cpp src/builtin_read.cpp src/builtin_realpath.cpp
|
||||
src/builtin_return.cpp src/builtin_set.cpp src/builtin_set_color.cpp
|
||||
src/builtin_source.cpp src/builtin_status.cpp src/builtin_string.cpp
|
||||
src/builtin_test.cpp src/builtin_ulimit.cpp src/builtin_wait.cpp src/builtin_eval.cpp
|
||||
src/color.cpp src/common.cpp src/complete.cpp src/env.cpp src/env_dispatch.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.
|
||||
@@ -172,13 +173,11 @@ function(FISH_LINK_DEPS_AND_SIGN target)
|
||||
endfunction(FISH_LINK_DEPS_AND_SIGN)
|
||||
|
||||
# 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_link_libraries(fishlib
|
||||
${CURSES_LIBRARY} ${CURSES_EXTRA_LIBRARY} Threads::Threads ${CMAKE_DL_LIBS}
|
||||
${PCRE2_LIB} ${Intl_LIBRARIES} ${ATOMIC_LIBRARY})
|
||||
target_include_directories(fishlib PRIVATE
|
||||
${CURSES_INCLUDE_DIRS})
|
||||
|
||||
# Define fish.
|
||||
add_executable(fish src/fish.cpp)
|
||||
@@ -212,15 +211,6 @@ include(cmake/Install.cmake)
|
||||
# Mac app.
|
||||
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
|
||||
# This could be implemented as target properties, but the script has the useful feature of only
|
||||
# checking the currently-staged commands
|
||||
|
||||
@@ -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.
|
||||
|
||||
292
CONTRIBUTING.rst
292
CONTRIBUTING.rst
@@ -3,73 +3,95 @@ Guidelines For Developers
|
||||
|
||||
This document provides guidelines for making changes to the fish-shell
|
||||
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)
|
||||
- Use automated tools to help you (including ``make test``, ``build_tools/style.fish`` and ``make lint``)
|
||||
Fish source should limit the C++ features it uses to those available in
|
||||
C++11. It should not use exceptions.
|
||||
|
||||
Contributing completions
|
||||
------------------------
|
||||
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.
|
||||
|
||||
Completion scripts are the most common contribution to fish, and they are very welcome.
|
||||
Versioning
|
||||
----------
|
||||
|
||||
In general, we'll take all well-written completion scripts for a command that is publically available.
|
||||
This means no private tools or personal scripts, and we do reserve the right to reject for other reasons.
|
||||
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``).
|
||||
|
||||
Before you try to contribute them to fish, consider if the authors of the tool you are completing want to maintain the script instead.
|
||||
Often that makes more sense, specifically because they can add new options to the script immediately once they add them,
|
||||
and don't have to maintain one completion script for multiple versions. If the authors no longer wish to maintain the script,
|
||||
they can of course always contact the fish maintainers to hand it over, preferably by opening a PR.
|
||||
This isn't a requirement - if the authors don't want to maintain it, or you simply don't want to contact them,
|
||||
you can contribute your script to fish.
|
||||
Include What You Use
|
||||
--------------------
|
||||
|
||||
Completion scripts should
|
||||
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.
|
||||
|
||||
1. Use as few dependencies as possible - try to use fish's builtins like ``string`` instead of ``grep`` and ``awk``,
|
||||
use ``python`` to read json instead of ``jq`` (because it's already a soft dependency for fish's tools)
|
||||
2. If it uses a common unix tool, use posix-compatible invocations - ideally it would work on GNU/Linux, macOS, the BSDs and other systems
|
||||
3. Option and argument descriptions should be kept short.
|
||||
The shorter the description, the more likely it is that fish can use more columns.
|
||||
4. Function names should start with ``__fish``, and functions should be kept in the completion file unless they're used elsewhere.
|
||||
5. Run ``fish_indent`` on your script.
|
||||
6. Try not to use minor convenience features right after they are available in fish - we do try to keep completion scripts backportable.
|
||||
If something has a real impact on the correctness or performance, feel free to use it,
|
||||
but if it is just a shortcut, please leave it.
|
||||
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>`__.
|
||||
|
||||
Put your completion script into share/completions/name-of-command.fish. If you have multiple commands, you need multiple files.
|
||||
To install the tool on OS X you’ll need to add a
|
||||
`formula <https://github.com/jasonmp85/homebrew-iwyu>`__ then install
|
||||
it:
|
||||
|
||||
If you want to add tests, you probably want to add a littlecheck test. See below for details.
|
||||
::
|
||||
|
||||
Contributing to fish's C++ core
|
||||
-------------------------------
|
||||
brew tap jasonmp85/iwyu
|
||||
brew install iwyu
|
||||
|
||||
Fish uses C++11. Newer C++ features should not be used to make it possible to use on older systems.
|
||||
On Ubuntu you can install it via ``apt-get``:
|
||||
|
||||
It does not use exceptions, they are disabled at build time with ``-fno-exceptions``.
|
||||
::
|
||||
|
||||
Don't introduce new dependencies unless absolutely necessary, and if you do,
|
||||
please make it optional with graceful failure if possible.
|
||||
Add any new dependencies to the README.rst under the *Running* and/or *Building* sections.
|
||||
sudo apt-get install iwyu
|
||||
|
||||
Linters
|
||||
-------
|
||||
Lint Free Code
|
||||
--------------
|
||||
|
||||
Automated analysis tools like cppcheck can point out
|
||||
Automated analysis tools like cppcheck and oclint can point out
|
||||
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
|
||||
that tend to confuse people.
|
||||
|
||||
To make linting the code easy there are two make targets: ``lint``,
|
||||
to lint any modified but not committed ``*.cpp`` files, and
|
||||
``lint-all`` to lint all files.
|
||||
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
|
||||
``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
|
||||
uncommitted work it will lint the files in the most recent commit.
|
||||
|
||||
Fish has custom cppcheck rules in the file ``.cppcheck.rule``. These
|
||||
help catch mistakes such as using ``wcwidth()`` rather than
|
||||
``fish_wcwidth()``. Please add a new rule if you find similar mistakes
|
||||
being made.
|
||||
|
||||
Fish also depends on ``diff`` and ``expect`` for its tests.
|
||||
|
||||
Dealing With Lint Warnings
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You are strongly encouraged to address a lint warning by refactoring the
|
||||
code, changing variable names, or whatever action is implied by the
|
||||
warning.
|
||||
|
||||
Suppressing Lint Warnings
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -91,20 +113,24 @@ following:
|
||||
|
||||
[src/complete.cpp:1727]: warning (nullPointerRedundantCheck): Either the condition 'cmd_node' is redundant or there is possible null pointer dereference: cmd_node.
|
||||
|
||||
Code Style
|
||||
----------
|
||||
Suppressing oclint warnings is more complicated to describe so I’ll
|
||||
refer you to the `OCLint
|
||||
HowTo <http://docs.oclint.org/en/latest/howto/suppress.html#annotations>`__
|
||||
on the topic.
|
||||
|
||||
To ensure your changes conform to the style rules run
|
||||
Ensuring Your Changes Conform to the Style Guides
|
||||
-------------------------------------------------
|
||||
|
||||
The following sections discuss the specific rules for the style that
|
||||
should be used when writing fish code. To ensure your changes conform to
|
||||
the style rules you simply need to run
|
||||
|
||||
::
|
||||
|
||||
build_tools/style.fish
|
||||
|
||||
before committing your change. That will run our autoformatters:
|
||||
|
||||
- ``git-clang-format`` for c++
|
||||
- ``fish_indent`` (shipped with fish) for fish script
|
||||
- ``black`` for python
|
||||
before committing your change. That will run ``git-clang-format`` to
|
||||
rewrite only the lines you’re modifying.
|
||||
|
||||
If you’ve already committed your changes that’s okay since it will then
|
||||
check the files in the most recent commit. This can be useful after
|
||||
@@ -122,10 +148,40 @@ If you want to check the style of the entire code base run
|
||||
That command will refuse to restyle any files if you have uncommitted
|
||||
changes.
|
||||
|
||||
Configuring Your Editor for Fish C++ Code
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
ViM
|
||||
^^^
|
||||
|
||||
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
|
||||
following C symbol. This means the ``gq`` key binding to reformat such
|
||||
comments doesn’t behave as expected. You can fix that by adding the
|
||||
following to your vimrc:
|
||||
|
||||
::
|
||||
|
||||
autocmd Filetype c,cpp setlocal comments^=:///
|
||||
|
||||
If you use ViM I recommend the `vim-clang-format
|
||||
plugin <https://github.com/rhysd/vim-clang-format>`__ by
|
||||
[@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
|
||||
^^^^^
|
||||
|
||||
If you use Emacs: TBD
|
||||
|
||||
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``:
|
||||
|
||||
::
|
||||
@@ -158,6 +214,22 @@ made to run fish_indent via e.g.
|
||||
(add-hook 'fish-mode-hook (lambda ()
|
||||
(add-hook 'before-save-hook 'fish_indent-before-save)))
|
||||
|
||||
Suppressing Reformatting of C++ Code
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you have a good reason for doing so you can tell ``clang-format`` to
|
||||
not reformat a block of code by enclosing it in comments like this:
|
||||
|
||||
::
|
||||
|
||||
// clang-format off
|
||||
code to ignore
|
||||
// clang-format on
|
||||
|
||||
However, as I write this there are no places in the code where we use
|
||||
this and I can’t think of any legitimate reasons for exempting blocks of
|
||||
code from clang-format.
|
||||
|
||||
Fish Script Style Guide
|
||||
-----------------------
|
||||
|
||||
@@ -219,27 +291,16 @@ Testing
|
||||
-------
|
||||
|
||||
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
|
||||
introduced. Even if you don’t 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
|
||||
of fish, especially if you are fixing a bug to help ensure there are no
|
||||
regressions in the future (i.e., we don’t 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
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
@@ -250,6 +311,32 @@ The tests can be run on your local computer on all operating systems.
|
||||
cmake path/to/fish-shell
|
||||
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 haven’t 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 you’re 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.
|
||||
|
||||
You’ll receive an email when the tests are complete telling you whether
|
||||
or not any tests failed.
|
||||
|
||||
You’ll find the configuration used to control Travis in the
|
||||
``.travis.yml`` file.
|
||||
|
||||
Git hooks
|
||||
~~~~~~~~~
|
||||
|
||||
@@ -314,6 +401,8 @@ To install the lint checkers on Mac OS X using Homebrew:
|
||||
|
||||
::
|
||||
|
||||
brew tap oclint/formulae
|
||||
brew install oclint
|
||||
brew install cppcheck
|
||||
|
||||
To install the lint checkers on Debian-based Linux distributions:
|
||||
@@ -321,9 +410,10 @@ To install the lint checkers on Debian-based Linux distributions:
|
||||
::
|
||||
|
||||
sudo apt-get install clang
|
||||
sudo apt-get install oclint
|
||||
sudo apt-get install cppcheck
|
||||
|
||||
Installing the Formatting Tools
|
||||
Installing the Reformatting Tools
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Mac OS X:
|
||||
@@ -336,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
|
||||
--------------------
|
||||
@@ -378,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
|
||||
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
|
||||
the source tree
|
||||
* copy ``messages.pot`` to ``po/LANG.po``
|
||||
|
||||
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``
|
||||
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
|
||||
command-line and graphical user interface programs.
|
||||
@@ -404,46 +497,3 @@ recommended deletions.
|
||||
Read the `translations
|
||||
wiki <https://github.com/fish-shell/fish-shell/wiki/Translations>`__ for
|
||||
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 you’ll 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
|
||||
|
||||
9
COPYING
9
COPYING
@@ -1,7 +1,7 @@
|
||||
Fish is a smart and user-friendly command line shell.
|
||||
|
||||
Copyright (C) 2005-2009 Axel Liljencrantz
|
||||
Copyright (C) 2009-2023 fish-shell contributors
|
||||
Copyright (C) 2009-2020 fish-shell contributors
|
||||
|
||||
fish is free software.
|
||||
|
||||
@@ -9,11 +9,10 @@ Most of fish is licensed under the GNU General Public License version 2, and
|
||||
you can redistribute it and/or modify it under the terms of the GNU GPL as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
fish also includes software licensed under the CMake license, the Python
|
||||
Software Foundation License version 2, the OpenBSD license, the ISC license,
|
||||
the NetBSD license, and the MIT license.
|
||||
fish also includes software licensed under the GNU Lesser General Public
|
||||
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
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
|
||||
@@ -31,19 +31,16 @@ else
|
||||
|
||||
all: .begin build/fish
|
||||
|
||||
.PHONY: .begin
|
||||
PHONY: .begin
|
||||
.begin:
|
||||
@which $(CMAKE) > /dev/null 2> /dev/null || \
|
||||
(echo 'Please install CMake and then re-run the `make` command!' 1>&2 && false)
|
||||
|
||||
.PHONY: build/fish
|
||||
build/fish: build/$(BUILDFILE)
|
||||
$(CMAKE) --build build
|
||||
|
||||
# Use build as an order-only dependency. This prevents the target from always being outdated
|
||||
# after a make run, and more importantly, doesn't clobber manually specified CMake options.
|
||||
build/$(BUILDFILE): | build
|
||||
cd build; $(CMAKE) .. -G "$(GENERATOR)" \
|
||||
build/$(BUILDFILE): build
|
||||
cd build; $(CMAKE) .. -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -G "$(GENERATOR)" \
|
||||
-DCMAKE_INSTALL_PREFIX="$(PREFIX)" -DCMAKE_EXPORT_COMPILE_COMMANDS=1
|
||||
|
||||
build:
|
||||
|
||||
77
README.rst
77
README.rst
@@ -1,8 +1,4 @@
|
||||
.. |Cirrus CI| image:: https://api.cirrus-ci.com/github/fish-shell/fish-shell.svg?branch=master
|
||||
:target: https://cirrus-ci.com/github/fish-shell/fish-shell
|
||||
:alt: Cirrus CI Build Status
|
||||
|
||||
`fish <https://fishshell.com/>`__ - the friendly interactive shell |Build Status| |Cirrus CI|
|
||||
`fish <https://fishshell.com/>`__ - the friendly interactive shell |Build Status|
|
||||
=================================================================================
|
||||
|
||||
fish is a smart and user-friendly command line shell for macOS, Linux,
|
||||
@@ -10,7 +6,8 @@ and the rest of the family. fish includes features like syntax
|
||||
highlighting, autosuggest-as-you-type, and fancy tab completions that
|
||||
just work, with no configuration required.
|
||||
|
||||
For downloads, screenshots and more, go to https://fishshell.com/.
|
||||
For more on fish’s design philosophy, see the `design
|
||||
document <https://fishshell.com/docs/current/design.html>`__.
|
||||
|
||||
Quick Start
|
||||
-----------
|
||||
@@ -23,6 +20,11 @@ magic phrase “unlike other shells”.
|
||||
Detailed user documentation is available by running ``help`` within
|
||||
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
|
||||
------------
|
||||
|
||||
@@ -37,8 +39,6 @@ fish can be installed:
|
||||
- using the `installer from fishshell.com <https://fishshell.com/>`__
|
||||
- as a `standalone app from fishshell.com <https://fishshell.com/>`__
|
||||
|
||||
Note: The minimum supported macOS version is 10.10 "Yosemite".
|
||||
|
||||
Packages for Linux
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -53,8 +53,8 @@ and can be installed using the following commands:
|
||||
::
|
||||
|
||||
sudo apt-add-repository ppa:fish-shell/release-3
|
||||
sudo apt update
|
||||
sudo apt install fish
|
||||
sudo apt-get update
|
||||
sudo apt-get install fish
|
||||
|
||||
Instructions for other distributions may be found at
|
||||
`fishshell.com <https://fishshell.com>`__.
|
||||
@@ -76,7 +76,7 @@ If packages are not available for your platform, GPG-signed tarballs are
|
||||
available from `fishshell.com <https://fishshell.com/>`__ and
|
||||
`fish-shell on
|
||||
GitHub <https://github.com/fish-shell/fish-shell/releases>`__. See the
|
||||
`Building <#building>`__ section for instructions.
|
||||
*Building* section for instructions.
|
||||
|
||||
Running fish
|
||||
------------
|
||||
@@ -92,25 +92,26 @@ Running fish requires:
|
||||
- some common \*nix system utilities (currently ``mktemp``), in
|
||||
addition to the basic POSIX utilities (``cat``, ``cut``, ``dirname``,
|
||||
``ls``, ``mkdir``, ``mkfifo``, ``rm``, ``sort``, ``tee``, ``tr``,
|
||||
``uname`` and ``sed`` at least, but the full coreutils plus ``find`` and
|
||||
``awk`` is preferred)
|
||||
- The gettext library, if compiled with
|
||||
``uname`` and ``sed`` at least, but the full coreutils plus find, sed
|
||||
and awk is preferred)
|
||||
- gettext (library and ``gettext`` command), if compiled with
|
||||
translation support
|
||||
|
||||
The following optional features also have specific requirements:
|
||||
|
||||
- builtin commands that have the ``--help`` option or print usage
|
||||
messages require ``nroff`` or ``mandoc`` for
|
||||
messages require ``ul`` and either ``nroff`` or ``mandoc`` for
|
||||
display
|
||||
- automated completion generation from manual pages requires Python 3.5+
|
||||
- the ``fish_config`` web configuration tool requires Python 3.5+ and a web browser
|
||||
- automated completion generation from manual pages requires Python
|
||||
(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
|
||||
bindings) require either the ``xsel``, ``xclip``,
|
||||
``wl-copy``/``wl-paste`` or ``pbcopy``/``pbpaste`` utilities
|
||||
- full completions for ``yarn`` and ``npm`` require the
|
||||
``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
|
||||
~~~~~~~~~~~~~~~~~
|
||||
@@ -149,16 +150,14 @@ Dependencies
|
||||
Compiling fish requires:
|
||||
|
||||
- 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)
|
||||
- PCRE2 (headers and libraries) - optional, this will be downloaded if missing
|
||||
- PCRE2 (headers and libraries) - a copy is included with fish
|
||||
- gettext (headers and libraries) - optional, for translation support
|
||||
|
||||
Sphinx is also optionally required to build the documentation from a
|
||||
cloned git repository.
|
||||
|
||||
Additionally, running the test suite requires Python 3.5+ and the pexpect package.
|
||||
|
||||
Building from source (all platforms) - Makefile generator
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -177,8 +176,6 @@ The install directory can be changed using the
|
||||
Building from source (macOS) - Xcode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Note: The minimum supported macOS version is 10.10 "Yosemite".
|
||||
|
||||
.. code:: bash
|
||||
|
||||
mkdir build; cd build
|
||||
@@ -196,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
|
||||
``-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 didn’t build!
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -219,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:
|
||||
|
||||
@@ -238,12 +222,17 @@ Contact Us
|
||||
Questions, comments, rants and raves can be posted to the official fish
|
||||
mailing list at https://lists.sourceforge.net/lists/listinfo/fish-users
|
||||
or join us on our `gitter.im
|
||||
channel <https://gitter.im/fish-shell/fish-shell>`__. Or use the `fish tag
|
||||
on Unix & Linux Stackexchange <https://unix.stackexchange.com/questions/tagged/fish>`__.
|
||||
There is also a fish tag on Stackoverflow, but it is typically a poor fit.
|
||||
channel <https://gitter.im/fish-shell/fish-shell>`__. Or use the `fish
|
||||
tag on
|
||||
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
|
||||
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
|
||||
:target: https://github.com/fish-shell/fish-shell/actions
|
||||
.. |Build Status| image:: https://travis-ci.org/fish-shell/fish-shell.svg?branch=master
|
||||
: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/
|
||||
|
||||
@@ -1089,3 +1089,4 @@ alias alias1020='something --arg1020'
|
||||
alias alias1021='something --arg1021'
|
||||
alias alias1022='something --arg1022'
|
||||
alias alias1023='something --arg1023'
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
for i in (seq 1000)
|
||||
for i in (seq 2000)
|
||||
command true
|
||||
end
|
||||
|
||||
|
||||
@@ -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 10)
|
||||
echo $dir/../../**
|
||||
end
|
||||
@@ -1,3 +0,0 @@
|
||||
for i in (seq 100000)
|
||||
math $i + $i
|
||||
end
|
||||
@@ -1,3 +1,3 @@
|
||||
for i in (seq 10000)
|
||||
for i in (seq 1000)
|
||||
echo $i
|
||||
end
|
||||
|
||||
@@ -1,43 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$#" -gt 2 -o "$#" -eq 0 ]; then
|
||||
echo "Usage: driver.sh /path/to/fish [/path/to/other/fish]"
|
||||
exit 1
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: driver.sh /path/to/fish"
|
||||
fi
|
||||
|
||||
FISH_PATH=$1
|
||||
FISH2_PATH=$2
|
||||
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
|
||||
basename "$benchmark"
|
||||
# If we have hyperfine, use it first to warm up the cache
|
||||
${FISH_PATH} --print-rusage-self "$benchmark" > /dev/null
|
||||
if command -v hyperfine >/dev/null 2>&1; then
|
||||
cmd1="$(quote "${FISH_PATH}") --no-config $(quote "$benchmark")"
|
||||
if [ -n "$FISH2_PATH" ]; then
|
||||
cmd2="$(quote "${FISH2_PATH}") --no-config $(quote "$benchmark")"
|
||||
hyperfine --warmup 3 "$cmd1" "$cmd2"
|
||||
else
|
||||
hyperfine --warmup 3 "$cmd1"
|
||||
fi
|
||||
hyperfine "${FISH_PATH} $benchmark > /dev/null"
|
||||
fi
|
||||
|
||||
[ -n "$FISH2_PATH" ] && echo "$FISH_PATH"
|
||||
"${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
|
||||
|
||||
done
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#!/bin/sh
|
||||
#!/usr/local/bin/fish
|
||||
|
||||
cppcheck --std=c++11 --quiet \
|
||||
--suppressions-list=build_tools/cppcheck.suppressions --inline-suppr \
|
||||
--rule-file=build_tools/cppcheck.rules \
|
||||
--force \
|
||||
${@:---enable=all ./src/}
|
||||
cppcheck --enable=all --std=posix --quiet ./src/
|
||||
|
||||
@@ -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
|
||||
@@ -14,7 +14,8 @@ set -g whitelist \
|
||||
# unclear what this is \
|
||||
l_constinit \
|
||||
# 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.
|
||||
set -g nm_regex '^([^ ]+) ([dDbB])'
|
||||
@@ -23,7 +24,8 @@ set -l total_globals 0
|
||||
set -l boring_files \
|
||||
fish_key_reader.cpp.o \
|
||||
fish_tests.cpp.o \
|
||||
fish_indent.cpp.o
|
||||
fish_indent.cpp.o \
|
||||
|
||||
|
||||
# return if we should ignore the given symbol name
|
||||
function should_ignore
|
||||
|
||||
@@ -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)
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env fish
|
||||
#
|
||||
# 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)
|
||||
# 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.
|
||||
set -l explicit_regex '.*\( *_ (([\'"]).+?(?<!\\\\)\\2) *\).*'
|
||||
|
||||
# Create temporary directory for these operations. OS X `mktemp` is somewhat restricted, so this block
|
||||
# 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
|
||||
rm -r /tmp/fish
|
||||
|
||||
mkdir -p $tmpdir/implicit/share/completions $tmpdir/implicit/share/functions
|
||||
mkdir -p $tmpdir/explicit/share/completions $tmpdir/explicit/share/functions
|
||||
mkdir -p /tmp/fish/implicit/share/completions /tmp/fish/implicit/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
|
||||
# Extract explicit attempts to translate a message. That is, those that are of the form
|
||||
# `(_ "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
|
||||
echo 'N_ "'(string replace --all '"' '\\"' -- $description)'"'
|
||||
end <$tmpdir/explicit/$f.tmp >$tmpdir/explicit/$f
|
||||
rm $tmpdir/explicit/$f.tmp
|
||||
end </tmp/fish/explicit/$f.tmp >/tmp/fish/explicit/$f
|
||||
rm /tmp/fish/explicit/$f.tmp
|
||||
|
||||
# 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
|
||||
# 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
|
||||
# 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
|
||||
# resulting string.
|
||||
echo 'N_ "'(string replace --all '"' '\\"' -- $description)'"'
|
||||
end <$tmpdir/implicit/$f.tmp >$tmpdir/implicit/$f
|
||||
rm $tmpdir/implicit/$f.tmp
|
||||
end </tmp/fish/implicit/$f.tmp >/tmp/fish/implicit/$f
|
||||
rm /tmp/fish/implicit/$f.tmp
|
||||
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 $tmpdir/implicit/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 /tmp/fish/implicit/share/*/*.fish
|
||||
|
||||
rm -r $tmpdir
|
||||
rm -r /tmp/fish
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env sh
|
||||
# Originally from the git sources (GIT-VERSION-GEN)
|
||||
# Presumably (C) Junio C Hamano <junkio@cox.net>
|
||||
# Reused under GPL v2.0
|
||||
@@ -9,26 +9,14 @@ set -e
|
||||
# Find the fish directory as two levels up from script directory.
|
||||
FISH_BASE_DIR="$( cd "$( dirname "$( dirname "$0" )" )" && pwd )"
|
||||
DEF_VER=unknown
|
||||
git_permission_failed=0
|
||||
|
||||
# First see if there is a version file (included in release tarballs),
|
||||
# then try git-describe, then default.
|
||||
if test -f version
|
||||
then
|
||||
VN=$(cat version) || VN="$DEF_VER"
|
||||
else
|
||||
if VN=$(git -C "$FISH_BASE_DIR" describe --always --dirty 2>/dev/null); then
|
||||
:
|
||||
else
|
||||
if test $? = 128; then
|
||||
# Current git versions return status 128
|
||||
# when run in a repo owned by another user.
|
||||
# Even for describe and everything.
|
||||
# This occurs for `sudo make install`.
|
||||
git_permission_failed=1
|
||||
fi
|
||||
VN="$DEF_VER"
|
||||
fi
|
||||
elif ! VN=$(git -C "$FISH_BASE_DIR" describe --always --dirty 2>/dev/null); then
|
||||
VN="$DEF_VER"
|
||||
fi
|
||||
|
||||
# If the first param is --stdout, then output to stdout and exit.
|
||||
@@ -40,20 +28,11 @@ fi
|
||||
|
||||
# Set the output directory as either the first param or cwd.
|
||||
test -n "$1" && OUTPUT_DIR=$1/ || OUTPUT_DIR=
|
||||
FBVF="${OUTPUT_DIR}FISH-BUILD-VERSION-FILE"
|
||||
FBVF=${OUTPUT_DIR}FISH-BUILD-VERSION-FILE
|
||||
|
||||
if test "$VN" = unknown && test -r "$FBVF" && test "$git_permission_failed" = 1
|
||||
if test -r $FBVF
|
||||
then
|
||||
# HACK: Git failed, so we keep the current version file.
|
||||
# This helps in case you built fish as a normal user
|
||||
# and then try to `sudo make install` it.
|
||||
date +%s > ${OUTPUT_DIR}fish-build-version-witness.txt
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -r "$FBVF"
|
||||
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
|
||||
VC="unset"
|
||||
fi
|
||||
@@ -62,7 +41,7 @@ fi
|
||||
# It looks like FISH_BUILD_VERSION="2.7.1-621-ga2f065e6"
|
||||
test "$VN" = "$VC" || {
|
||||
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
|
||||
|
||||
@@ -2,27 +2,10 @@
|
||||
# the version installed by HomeBrew doesn't have useful mappings for the
|
||||
# system provided headers. This also has mappings for FreeBSD.
|
||||
[
|
||||
{ include: ["<__functional_base>", private, "<functional>", public ] },
|
||||
{ include: ["<__mutex_base>", private, "<mutex>", public ] },
|
||||
{ include: ["@<__algorithm/.*>", "private", "<algorithm>", "public"] },
|
||||
{ include: ["@<__iterator/.*>", "private", "<iterator>", "public"] },
|
||||
{ include: ["@<__functional/.*>", "private", "<functional>", "public"] },
|
||||
{ include: ["@<__memory/.*>", "private", "<memory>", "public"] },
|
||||
{ include: ["@<__utility/.*>", "private", "<utility>", "public"] },
|
||||
{ include: ["@<__chrono/.*>", "private", "<chrono>", "public"] },
|
||||
{ include: ["@<__numeric/.*>", "private", "<numeric>", "public"] },
|
||||
{ include: ["@<__random/.*>", "private", "<random>", "public"] },
|
||||
{ include: ["@<__locale/.*>", "private", "<locale>", "public"] },
|
||||
{ include: ["@<xlocale/.*>", "private", "<xlocale.h>", "public"] },
|
||||
# ratio false positive. See https://groups.google.com/g/include-what-you-use/c/OKVkkWUlx44
|
||||
{ include: ["<ratio>", "public", "<chrono>", "public"] },
|
||||
{ include: ["<__locale>", "private", "<locale>", "public"] },
|
||||
{ include: ["<_ctype.h>", "private", "<ctype.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_once_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_mutex_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_rwlock_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_mutexattr_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_attr_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_cond_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_key_t.h>", "private", "<pthread.h>", "public"] },
|
||||
@@ -37,7 +20,7 @@
|
||||
{ include: ["<sys/fcntl.h>", "private", "<fcntl.h>", "public"] },
|
||||
{ include: ["<sys/_types/_seek_set.h>", "private", "<fcntl.h>", "public"] },
|
||||
{ include: ["<sys/_types/_mbstate_t.h>", "private", "<wchar.h>", "public"] },
|
||||
{ include: ["<iosfwd>", "public", "<string>", "public"] },
|
||||
{ include: ["<iosfwd>", "private", "<string>", "public"] },
|
||||
{ include: ["<sys/_stdint.h>", "private", "<stdint.h>", "public"] },
|
||||
{ include: ["<sys/_types/_s_ifmt.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_size_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
@@ -68,6 +51,7 @@
|
||||
{ include: ["<sys/_types/_va_list.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_sigset_t.h>", "private", "<signal.h>", "public"] },
|
||||
{ include: ["<sys/signal.h>", "private", "<signal.h>", "public"] },
|
||||
{ include: ["<strings.h>", "private", "<string.h>", "public"] },
|
||||
{ include: ["<sys/termios.h>", "private", "<termios.h>", "public"] },
|
||||
{ include: ["<sys/_termios.h>", "private", "<termios.h>", "public"] },
|
||||
{ include: ["<sys/ttycom.h>", "private", "<termios.h>", "public"] },
|
||||
@@ -77,7 +61,7 @@
|
||||
{ include: ["<sys/_types/_wint_t.h>", "private", "<stddef.h>", "public"] },
|
||||
{ include: ["<sys/_select.h>", "private", "<select.h>", "public"] },
|
||||
{ include: ["<sys/cdefs.h>", "private", "<unistd.h>", "public"] },
|
||||
{ include: ["<istream>", "public", "<iostream>", "public"] },
|
||||
{ include: ["<istream>", "private", "<iostream>", "public"] },
|
||||
{ include: ["<sys/_endian.h>", "private", "<netinet/in.h>", "public"] },
|
||||
{ include: ["<sys/_types/_timespec.h>", "private", "<time.h>", "public"] },
|
||||
{ include: ["<sys/_timespec.h>", "private", "<time.h>", "public"] },
|
||||
@@ -86,30 +70,22 @@
|
||||
{ include: ["<__mutex_base>", "private", "<mutex>", "public"] },
|
||||
{ include: ["<__hash_table>", "private", "<unordered_map>", "public"] },
|
||||
{ include: ["<__hash_table>", "private", "<unordered_set>", "public"] },
|
||||
{ include: ['"../common.h"', "public", '"common.h"', "public"] },
|
||||
# We provide our own assert. including assert.h/cassert spoils it and redefines the macro
|
||||
{ symbol: ["assert", "private", '"common.h"', "public"] },
|
||||
{ symbol: ["assert", "private", '"../common.h"', "public"] },
|
||||
{ symbol: ["wcstring", "private", '"common.h"', "public"] },
|
||||
{ symbol: ["wcstring", "private", '"../common.h"', "public"] },
|
||||
{ symbol: ["wcstring_list_t", "private", '"common.h"', "public"] },
|
||||
{ symbol: ["wcstring_list_t", "private", '"../common.h"', "public"] },
|
||||
{ symbol: ["wcstring", "private", '"flog.h"', "public"] },
|
||||
{ symbol: ["wcstring_list_t", "private", '"flog.h"', "public"] },
|
||||
# { include: ["<>", "private", "<>", "public"] },
|
||||
|
||||
{ symbol: ["size_t", "private", "<cstddef>", "public"] },
|
||||
{ symbol: ["mutex", "private", "<mutex>", "public"] },
|
||||
{ symbol: ["sig_atomic_t", "private", "<csignal>", "public"] },
|
||||
{ symbol: ["va_end", "private", "<stdarg.h>", "public"] },
|
||||
{ symbol: ["va_list", "private", "<stdarg.h>", "public"] },
|
||||
{ symbol: ["va_start", "private", "<stdarg.h>", "public"] },
|
||||
{ symbol: ["NULL", "private", "<cstddef>", "public"] },
|
||||
{ symbol: ["NULL", "private", "<stddef.h>", "public"] },
|
||||
{ symbol: ["NULL", "private", "<stdlib.h>", "public"] },
|
||||
{ symbol: ["NULL", "private", "<stdio.h>", "public"] },
|
||||
{ symbol: ["NULL", "private", "<unistd.h>", "public"] },
|
||||
{ symbol: ["off_t", "private", "<unistd.h>", "public"] },
|
||||
{ symbol: ["off_t", "private", "<sys/types.h>", "public"] },
|
||||
{ symbol: ["size_t", "private", "<cstddef>", "public"] },
|
||||
{ symbol: ["ssize_t", "private", "<cstddef>", "public"] },
|
||||
{ symbol: ["size_t", "private", "<stddef.h>", "public"] },
|
||||
{ symbol: ["ssize_t", "private", "<stddef.h>", "public"] },
|
||||
{ symbol: ["intptr_t", "private", "<unistd.h>", "public"] },
|
||||
{ symbol: ["gid_t", "private", "<unistd.h>", "public"] },
|
||||
{ symbol: ["uid_t", "private", "<unistd.h>", "public"] },
|
||||
@@ -118,54 +94,16 @@
|
||||
{ symbol: ["uid_t", "private", "<sys/types.h>", "public"] },
|
||||
{ symbol: ["gid_t", "private", "<sys/types.h>", "public"] },
|
||||
{ symbol: ["timeval", "private", "<sys/time.h>", "public"] },
|
||||
{ symbol: ["__uint32_t", "private", "<cstdint>", "public"] },
|
||||
{ symbol: ["uint32_t", "private", "<cstdint>", "public"] },
|
||||
{ symbol: ["intptr_t", "private", "<cstdint>", "public"] },
|
||||
{ symbol: ["__uint32_t", "private", "<stdint.h>", "public"] },
|
||||
{ symbol: ["uint32_t", "private", "<stdint.h>", "public"] },
|
||||
{ symbol: ["intptr_t", "private", "<stdint.h>", "public"] },
|
||||
{ symbol: ["tparm", "private", "<ncurses.h>", "public"] },
|
||||
{ symbol: ["tigetflag", "private", "<ncurses.h>", "public"] },
|
||||
{ symbol: ["ERR", "private", "<ncurses.h>", "public"] },
|
||||
{ symbol: ["OK", "private", "<ncurses.h>", "public"] },
|
||||
{ symbol: ["select", "private", "<sys/select.h>", "public"] },
|
||||
{ symbol: ["_LIBCPP_VERSION", "private", "<cstddef>", "public"] },
|
||||
{ symbol: ["_LIBCPP_VERSION", "private", "<stddef.h>", "public"] },
|
||||
{ symbol: ["_LIBCPP_VERSION", "private", "<unistd.h>", "public"] },
|
||||
{ symbol: ["MB_CUR_MAX", "private", "<cstdlib>", "public"] },
|
||||
{ symbol: ["MB_LEN_MAX", "private", "<cstdlib>", "public"] },
|
||||
{ symbol: ["WEOF", "private", "<cwctype>", "public"] },
|
||||
{ symbol: [ "std::declval", private, "<utility>", public ] },
|
||||
{ symbol: [ "std::forward", private, "<utility>", public ] },
|
||||
{ symbol: [ "std::move", private, "<utility>", public ] },
|
||||
{ symbol: [ "std::nullptr_t", private, "<cstddef>", public ] },
|
||||
{ symbol: [ "std::string", private, "<string>", public ] },
|
||||
{ symbol: [ "std::isalnum", private, "<locale>", public ] },
|
||||
{ symbol: [ "std::toupper", private, "<locale>", public ] },
|
||||
{ symbol: [ "sem_t", private, "<semaphore.h>", public ] },
|
||||
{ symbol: [ "sem_post", private, "<semaphore.h>", public ] },
|
||||
{ symbol: [ "sem_wait", private, "<semaphore.h>", public ] },
|
||||
{ symbol: [ "sem_init", private, "<semaphore.h>", public ] },
|
||||
{ symbol: [ "sem_destroy", private, "<semaphore.h>", public ] },
|
||||
{ symbol: [ "FD_SETSIZE", private, "<sys/select.h>", public ] },
|
||||
{ symbol: [ "locale_t", private, "<locale>", public ] },
|
||||
{ include: [ "<assert.h>", public, "<cassert>", public ] },
|
||||
{ include: [ "<complex.h>", public, "<ccomplex>", public ] },
|
||||
{ include: [ "<ctype.h>", public, "<cctype>", public ] },
|
||||
{ include: [ "<errno.h>", public, "<cerrno>", public ] },
|
||||
{ include: [ "<fenv.h>", public, "<cfenv>", public ] },
|
||||
{ include: [ "<float.h>", public, "<cfloat>", public ] },
|
||||
{ include: [ "<inttypes.h>", public, "<cinttypes>", public ] },
|
||||
{ include: [ "<iso646.h>", public, "<ciso646>", public ] },
|
||||
{ include: [ "<limits.h>", public, "<climits>", public ] },
|
||||
{ include: [ "<locale.h>", public, "<clocale>", public ] },
|
||||
{ include: [ "<math.h>", public, "<cmath>", public ] },
|
||||
{ include: [ "<setjmp.h>", public, "<csetjmp>", public ] },
|
||||
{ include: [ "<signal.h>", public, "<csignal>", public ] },
|
||||
{ include: [ "<stdalign.h>", public, "<cstdalign>", public ] },
|
||||
{ include: [ "<stdarg.h>", public, "<cstdarg>", public ] },
|
||||
{ include: [ "<stdbool.h>", public, "<cstdbool>", public ] },
|
||||
{ include: [ "<stddef.h>", public, "<cstddef>", public ] },
|
||||
{ include: [ "<stdlib.h>", public, "<cstdlib>", public ] },
|
||||
{ include: [ "<string.h>", public, "<cstring>", public ] },
|
||||
{ include: [ "<tgmath.h>", public, "<ctgmath>", public ] },
|
||||
{ include: [ "<time.h>", public, "<ctime>", public ] },
|
||||
{ include: [ "<uchar.h>", public, "<cuchar>", public ] },
|
||||
{ include: [ "<wchar.h>", public, "<cwchar>", public ] },
|
||||
{ include: [ "<wctype.h>", public, "<cwctype>", public ] },
|
||||
{ include: [ "<_xlocale.h>", private, "<xlocale.h>", public ] },
|
||||
|
||||
{ symbol: ["MB_CUR_MAX", "private", "<xlocale.h>", "public"] },
|
||||
{ symbol: ["MB_CUR_MAX", "private", "<stdlib.h>", "public"] },
|
||||
]
|
||||
|
||||
@@ -18,11 +18,11 @@ argparse a/all p/project= -- $argv
|
||||
# We only want -D and -I options to be passed thru to cppcheck.
|
||||
for arg in $argv
|
||||
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
|
||||
set -a cppcheck_args (string split -- ' ' $arg)
|
||||
set cppcheck_args $cppcheck_args $arg
|
||||
else if string match -q -- '-iquote*' $arg
|
||||
set -a cppcheck_args (string split -- ' ' $arg)
|
||||
set cppcheck_args $cppcheck_args $arg
|
||||
end
|
||||
end
|
||||
|
||||
@@ -83,7 +83,20 @@ if set -q c_files[1]
|
||||
echo ========================================
|
||||
echo Running cppcheck
|
||||
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 ========================================
|
||||
|
||||
@@ -13,9 +13,7 @@ if not contains -- $TAG (git tag)
|
||||
end
|
||||
|
||||
set -l committers_to_tag (mktemp)
|
||||
or exit 1
|
||||
set -l committers_from_tag (mktemp)
|
||||
or exit 1
|
||||
|
||||
# You might think it would be better to case-insensitively sort/compare the names
|
||||
# to produce a more natural-looking list.
|
||||
|
||||
@@ -6,6 +6,7 @@ from __future__ import unicode_literals
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
from collections import deque
|
||||
import datetime
|
||||
import io
|
||||
import re
|
||||
@@ -13,39 +14,15 @@ import shlex
|
||||
import subprocess
|
||||
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.
|
||||
RUN_RE = re.compile(COMMENT_RE + r"RUN:\s+(.*)\n")
|
||||
REQUIRES_RE = re.compile(COMMENT_RE + r"REQUIRES:\s+(.*)\n")
|
||||
RUN_RE = re.compile(r"\s*#\s*RUN:\s+(.*)\n")
|
||||
|
||||
# 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.
|
||||
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):
|
||||
def __init__(self):
|
||||
@@ -55,6 +32,10 @@ class Config(object):
|
||||
self.colorize = False
|
||||
# Whether to show which file was tested.
|
||||
self.progress = False
|
||||
# How many after lines to print
|
||||
self.after = 5
|
||||
# How many before lines to print
|
||||
self.before = 5
|
||||
|
||||
def colors(self):
|
||||
""" Return a dictionary mapping color names to ANSI escapes """
|
||||
@@ -96,6 +77,8 @@ def esc(m):
|
||||
map = {
|
||||
"\n": "\\n",
|
||||
"\\": "\\\\",
|
||||
"'": "\\'",
|
||||
'"': '\\"',
|
||||
"\a": "\\a",
|
||||
"\b": "\\b",
|
||||
"\f": "\\f",
|
||||
@@ -135,26 +118,6 @@ class Line(object):
|
||||
self.number = number
|
||||
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):
|
||||
""" Return a substring of our line with the given text, preserving number and file. """
|
||||
return Line(text, self.number, self.file)
|
||||
@@ -166,16 +129,10 @@ class Line(object):
|
||||
def is_empty_space(self):
|
||||
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):
|
||||
"""A command to run on a given Checker.
|
||||
|
||||
""" A command to run on a given Checker.
|
||||
|
||||
Attributes:
|
||||
args: Unexpanded shell command as a string.
|
||||
"""
|
||||
@@ -192,17 +149,17 @@ class RunCmd(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.check = check
|
||||
self.testrun = testrun
|
||||
self.error_annotation_lines = None
|
||||
self.diff = diff
|
||||
self.lines = lines
|
||||
self.checks = checks
|
||||
self.signal = None
|
||||
self.error_annotation_line = None
|
||||
# The output that comes *after* the failure.
|
||||
self.after = after
|
||||
self.before = before
|
||||
|
||||
def message(self):
|
||||
afterlines = self.testrun.config.after
|
||||
fields = self.testrun.config.colors()
|
||||
fields["name"] = self.testrun.name
|
||||
fields["subbed_command"] = self.testrun.subbed_command
|
||||
@@ -211,7 +168,7 @@ class TestFailure(object):
|
||||
{
|
||||
"output_file": self.line.file,
|
||||
"output_lineno": self.line.number,
|
||||
"output_line": self.line.escaped_text(),
|
||||
"output_line": self.line.text.rstrip("\n"),
|
||||
}
|
||||
)
|
||||
if self.check:
|
||||
@@ -219,17 +176,12 @@ class TestFailure(object):
|
||||
{
|
||||
"input_file": self.check.line.file,
|
||||
"input_lineno": self.check.line.number,
|
||||
"input_line": self.check.line.escaped_text(),
|
||||
"input_line": self.check.line.text,
|
||||
"check_type": self.check.type,
|
||||
}
|
||||
)
|
||||
filemsg = "" if self.testrun.config.progress else " in {name}"
|
||||
fmtstrs = ["{RED}Failure{RESET}" + filemsg + ":", ""]
|
||||
if self.signal:
|
||||
fmtstrs += [
|
||||
" Process was killed by signal {BOLD}" + self.signal + "{RESET}",
|
||||
""
|
||||
]
|
||||
if self.line and self.check:
|
||||
fmtstrs += [
|
||||
" The {check_type} on line {input_lineno} wants:",
|
||||
@@ -254,97 +206,24 @@ class TestFailure(object):
|
||||
" {BOLD}{output_line}{RESET}",
|
||||
"",
|
||||
]
|
||||
if self.error_annotation_lines:
|
||||
fields["error_annotation"] = " ".join(
|
||||
[x.text for x in self.error_annotation_lines]
|
||||
)
|
||||
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
|
||||
)
|
||||
if self.error_annotation_line:
|
||||
fields["error_annotation"] = self.error_annotation_line.text
|
||||
fields["error_annotation_lineno"] = self.error_annotation_line.number
|
||||
fmtstrs += [
|
||||
" additional output on stderr:{error_annotation_lineno}:",
|
||||
" {BOLD}{error_annotation}{RESET}",
|
||||
]
|
||||
if self.diff:
|
||||
fmtstrs += [" Context:"]
|
||||
lasthi = 0
|
||||
lastcheckline = None
|
||||
for d in self.diff.get_grouped_opcodes():
|
||||
for op, alo, ahi, blo, bhi in d:
|
||||
color = "{BOLD}"
|
||||
if op == "replace" or op == "delete":
|
||||
color = "{RED}"
|
||||
# We got a new chunk, so we print a marker.
|
||||
if alo > lasthi:
|
||||
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 = (
|
||||
"on line "
|
||||
+ str(b.line.number)
|
||||
+ ": {BLUE}"
|
||||
+ b.line.escaped_text(for_formatting=True)
|
||||
+ "{RESET}"
|
||||
)
|
||||
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("")
|
||||
if self.before:
|
||||
fields["before_output"] = " ".join(self.before)
|
||||
fields["additional_output"] = " ".join(self.after[:afterlines])
|
||||
fmtstrs += [
|
||||
" Context:",
|
||||
" {BOLD}{before_output} {RED}{output_line}{RESET} <= does not match '{LIGHTBLUE}{input_line}{RESET}'",
|
||||
" {BOLD}{additional_output}{RESET}",
|
||||
]
|
||||
elif self.after:
|
||||
fields["additional_output"] = " ".join(self.after[:afterlines])
|
||||
fmtstrs += [" additional output:", " {BOLD}{additional_output}{RESET}"]
|
||||
fmtstrs += [" when running command:", " {subbed_command}"]
|
||||
return "\n".join(fmtstrs).format(**fields)
|
||||
|
||||
@@ -354,8 +233,8 @@ class TestFailure(object):
|
||||
|
||||
|
||||
def perform_substitution(input_str, subs):
|
||||
"""Perform the substitutions described by subs to str
|
||||
Return the substituted string.
|
||||
""" Perform the substitutions described by subs to str
|
||||
Return the substituted string.
|
||||
"""
|
||||
# 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.
|
||||
@@ -375,20 +254,6 @@ def perform_substitution(input_str, subs):
|
||||
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):
|
||||
def __init__(self, name, runcmd, checker, subs, config):
|
||||
self.name = name
|
||||
@@ -402,95 +267,74 @@ class TestRun(object):
|
||||
# Reverse our lines and checks so we can pop off the end.
|
||||
lineq = lines[::-1]
|
||||
checkq = checks[::-1]
|
||||
usedlines = []
|
||||
usedchecks = []
|
||||
mismatches = []
|
||||
# We keep the last couple of lines in a deque so we can show context.
|
||||
before = deque(maxlen=self.config.before)
|
||||
while lineq and checkq:
|
||||
line = lineq[-1]
|
||||
check = checkq[-1]
|
||||
if check == line:
|
||||
if check.regex.match(line.text):
|
||||
# This line matched this checker, continue on.
|
||||
usedlines.append(line)
|
||||
usedchecks.append(check)
|
||||
lineq.pop()
|
||||
checkq.pop()
|
||||
before.append(line)
|
||||
elif line.is_empty_space():
|
||||
# Skip all whitespace input lines.
|
||||
lineq.pop()
|
||||
else:
|
||||
usedlines.append(line)
|
||||
usedchecks.append(check)
|
||||
mismatches.append((line, check))
|
||||
# Failed to match.
|
||||
lineq.pop()
|
||||
checkq.pop()
|
||||
|
||||
# Drain empties
|
||||
line.text = escape_string(line.text.strip()) + "\n"
|
||||
# Add context, ignoring empty lines.
|
||||
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():
|
||||
lineq.pop()
|
||||
|
||||
# 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)
|
||||
|
||||
# If we have no more output, there's no reason to give
|
||||
# SCREENFULS of text.
|
||||
# So we truncate the check list.
|
||||
if len(usedchecks) > len(usedlines):
|
||||
usedchecks = usedchecks[:len(usedlines) + 5]
|
||||
|
||||
# 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.
|
||||
# If there's still lines or checkers, we have a failure.
|
||||
# Otherwise it's success.
|
||||
if mismatches:
|
||||
return TestFailure(
|
||||
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
|
||||
)
|
||||
if lineq:
|
||||
return TestFailure(lineq[-1], None, self)
|
||||
elif checkq:
|
||||
return TestFailure(
|
||||
None, checkq[-1], self, diff=diff, lines=usedlines, checks=usedchecks
|
||||
)
|
||||
return TestFailure(None, checkq[-1], self)
|
||||
else:
|
||||
# Success!
|
||||
return None
|
||||
|
||||
def run(self):
|
||||
""" Run the command. Return a TestFailure, or None. """
|
||||
|
||||
def split_by_newlines(s):
|
||||
"""Decode a string and split it by newlines only,
|
||||
retaining the newlines.
|
||||
""" Decode a string and split it by newlines only,
|
||||
retaining the newlines.
|
||||
"""
|
||||
return [s + "\n" for s in s.decode("utf-8").split("\n")]
|
||||
|
||||
PIPE = subprocess.PIPE
|
||||
if self.config.verbose:
|
||||
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()
|
||||
# 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,
|
||||
# most likely when the last command in a shell script doesn't exist.
|
||||
# So we check if the command *we execute* exists, and complain then.
|
||||
# Technically it's also possible to return it in other conditions.
|
||||
# Practically, that's *probably* not going to happen.
|
||||
status = proc.returncode
|
||||
cmd = shlex.split(self.subbed_command)[0]
|
||||
if status == 127 and not find_command(cmd):
|
||||
raise CheckerError("Command could not be found: " + cmd)
|
||||
if status == 126 and not find_command(cmd):
|
||||
raise CheckerError("Command is not executable: " + cmd)
|
||||
if status == 127:
|
||||
raise CheckerError("Command could not be found: " + self.subbed_command)
|
||||
|
||||
outlines = [
|
||||
Line(text, idx + 1, "stdout")
|
||||
@@ -507,38 +351,8 @@ class TestRun(object):
|
||||
# non-matching or unmatched stderr text, then annotate the outfail
|
||||
# with it.
|
||||
if outfail and errfail and errfail.line:
|
||||
outfail.error_annotation_lines = errlines[errfail.line.number - 1 :]
|
||||
# Trim a trailing newline
|
||||
if outfail.error_annotation_lines[-1].text == "\n":
|
||||
del outfail.error_annotation_lines[-1]
|
||||
failure = outfail if outfail else errfail
|
||||
|
||||
if failure and status < 0:
|
||||
# Process was killed by a signal and failed,
|
||||
# add a message.
|
||||
import signal
|
||||
# Unfortunately strsignal only exists in python 3.8+,
|
||||
# and signal.signals is 3.5+.
|
||||
if hasattr(signal, "Signals"):
|
||||
try:
|
||||
sig = signal.Signals(-status)
|
||||
failure.signal = sig.name + " (" + signal.strsignal(sig.value) + ")"
|
||||
except ValueError:
|
||||
failure.signal = str(-status)
|
||||
else:
|
||||
# No easy way to get the full list,
|
||||
# make up a dict.
|
||||
signals = {
|
||||
signal.SIGABRT: "SIGABRT",
|
||||
signal.SIGBUS: "SIGBUS",
|
||||
signal.SIGFPE: "SIGFPE",
|
||||
signal.SIGILL: "SIGILL",
|
||||
signal.SIGSEGV: "SIGSEGV",
|
||||
signal.SIGTERM: "SIGTERM",
|
||||
}
|
||||
failure.signal = signals.get(-status, str(-status))
|
||||
|
||||
return failure
|
||||
outfail.error_annotation_line = errfail.line
|
||||
return outfail if outfail else errfail
|
||||
|
||||
|
||||
class CheckCmd(object):
|
||||
@@ -547,28 +361,6 @@ class CheckCmd(object):
|
||||
self.type = checktype
|
||||
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
|
||||
def parse(line, checktype):
|
||||
# type: (Line) -> CheckCmd
|
||||
@@ -628,19 +420,14 @@ class Checker(object):
|
||||
|
||||
# Find run commands.
|
||||
self.runcmds = [RunCmd.parse(sl) for sl in group1s(RUN_RE)]
|
||||
self.shebang_cmd = None
|
||||
if not self.runcmds:
|
||||
# If no RUN command has been given, fall back to the shebang.
|
||||
if lines[0].text.startswith("#!"):
|
||||
# Remove the "#!" at the beginning, and the newline at the end.
|
||||
cmd = lines[0].text[2:-1]
|
||||
self.shebang_cmd = cmd
|
||||
self.runcmds = [RunCmd(cmd + " %s", lines[0])]
|
||||
self.runcmds = [RunCmd(lines[0].text[2:-1] + " %s", lines[0])]
|
||||
else:
|
||||
raise CheckerError("No runlines ('# RUN') found")
|
||||
|
||||
self.requirecmds = [RunCmd.parse(sl) for sl in group1s(REQUIRES_RE)]
|
||||
|
||||
# Find check cmds.
|
||||
self.outchecks = [
|
||||
CheckCmd.parse(sl, "CHECK") for sl in group1s(CHECK_STDOUT_RE)
|
||||
@@ -655,21 +442,6 @@ def check_file(input_file, name, subs, config, failure_handler):
|
||||
success = True
|
||||
lines = Line.readfile(input_file, name)
|
||||
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:
|
||||
failure = TestRun(name, runcmd, checker, subs, config).run()
|
||||
if failure:
|
||||
@@ -684,8 +456,8 @@ def check_path(path, subs, config, failure_handler):
|
||||
|
||||
|
||||
def parse_subs(subs):
|
||||
"""Given a list of input substitutions like 'foo=bar',
|
||||
return a dictionary like {foo:bar}, or exit if invalid.
|
||||
""" Given a list of input substitutions like 'foo=bar',
|
||||
return a dictionary like {foo:bar}, or exit if invalid.
|
||||
"""
|
||||
result = {}
|
||||
for sub in subs:
|
||||
@@ -725,14 +497,23 @@ def get_argparse():
|
||||
help="Show the files to be checked",
|
||||
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(
|
||||
"-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
|
||||
|
||||
|
||||
@@ -742,16 +523,19 @@ def main():
|
||||
def_subs = {"%": "%"}
|
||||
def_subs.update(parse_subs(args.substitute))
|
||||
|
||||
tests_count = 0
|
||||
failed = False
|
||||
skip_count = 0
|
||||
failure_count = 0
|
||||
config = Config()
|
||||
config.colorize = args.force_color or sys.stdout.isatty()
|
||||
config.colorize = sys.stdout.isatty()
|
||||
config.progress = args.progress
|
||||
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:
|
||||
tests_count += 1
|
||||
fields["path"] = path
|
||||
if config.progress:
|
||||
print("Testing file {path} ... ".format(**fields), end="")
|
||||
@@ -759,33 +543,17 @@ def main():
|
||||
subs = def_subs.copy()
|
||||
subs["s"] = path
|
||||
starttime = datetime.datetime.now()
|
||||
ret = check_path(path, subs, config, TestFailure.print_message)
|
||||
if ret is SKIP:
|
||||
skip_count += 1
|
||||
if not ret:
|
||||
failed = True
|
||||
if not check_path(path, subs, config, TestFailure.print_message):
|
||||
failure_count += 1
|
||||
elif config.progress:
|
||||
endtime = datetime.datetime.now()
|
||||
duration_ms = round((endtime - starttime).total_seconds() * 1000)
|
||||
reason = "ok"
|
||||
color = "{GREEN}"
|
||||
if ret is SKIP:
|
||||
reason = "SKIPPED"
|
||||
color = "{BLUE}"
|
||||
print(
|
||||
(color + "{reason}{RESET} ({duration} ms)").format(
|
||||
duration=duration_ms, reason=reason, **fields
|
||||
"{GREEN}ok{RESET} ({duration} ms)".format(
|
||||
duration=duration_ms, **fields
|
||||
)
|
||||
)
|
||||
|
||||
# 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)
|
||||
sys.exit(failure_count)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,22 +1,76 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Helper to notarize an .app.zip or .pkg file.
|
||||
# Based on https://www.logcg.com/en/archives/3222.html
|
||||
|
||||
set -e
|
||||
|
||||
die() { echo "$*" 1>&2 ; exit 1; }
|
||||
|
||||
check_status() {
|
||||
echo "STATUS" $1
|
||||
}
|
||||
|
||||
test "$#" -ge 1 || die "No paths specified."
|
||||
get_req_uuid() {
|
||||
RESPONSE=$(</dev/stdin)
|
||||
if echo "$RESPONSE" | egrep -q "RequestUUID"; then
|
||||
echo "$RESPONSE" | egrep RequestUUID | awk '{print $3'}
|
||||
elif echo "$RESPONSE" | egrep -q "The upload ID is "; then
|
||||
echo "$RESPONSE" | egrep -p "The upload ID is [-a-z0-9]+" | awk '{print $5}'
|
||||
else
|
||||
die "Could not get Request UUID"
|
||||
fi
|
||||
}
|
||||
|
||||
for INPUT in "$@"; do
|
||||
echo "Processing $INPUT"
|
||||
test -f "$INPUT" || die "Not a file: $INPUT"
|
||||
ext="${INPUT##*.}"
|
||||
(test "$ext" = "zip" || test "$ext" = "pkg") || die "Unrecognized extension: $ext"
|
||||
INPUT=$1
|
||||
AC_USER=$2
|
||||
|
||||
xcrun notarytool submit "$INPUT" --keychain-profile AC_PASSWORD --wait
|
||||
test -z "$AC_USER" && die "AC_USER not specified as second param"
|
||||
test -z "$INPUT" && die "No path specified"
|
||||
test -f "$INPUT" || die "Not a file: $INPUT"
|
||||
|
||||
ext="${INPUT##*.}"
|
||||
(test "$ext" = "zip" || test "$ext" = "pkg") || die "Unrecognized extension: $ext"
|
||||
|
||||
LOGFILE=$(mktemp -t mac_notarize_log)
|
||||
AC_PASS="@keychain:AC_PASSWORD"
|
||||
echo "Logs at $LOGFILE"
|
||||
|
||||
NOTARIZE_UUID=$(xcrun altool --notarize-app \
|
||||
--primary-bundle-id "com.ridiculousfish.fish-shell" \
|
||||
--username "$AC_USER" \
|
||||
--password "$AC_PASS" \
|
||||
--file "$INPUT" 2>&1 |
|
||||
tee -a "$LOGFILE" |
|
||||
get_req_uuid)
|
||||
|
||||
test -z "$NOTARIZE_UUID" && cat "$LOGFILE" && die "Could not get RequestUUID"
|
||||
echo "RequestUUID: $NOTARIZE_UUID"
|
||||
|
||||
success=0
|
||||
for i in $(seq 20); do
|
||||
echo "Checking progress..."
|
||||
PROGRESS=$(xcrun altool --notarization-info "${NOTARIZE_UUID}" \
|
||||
-u "$AC_USER" \
|
||||
-p "$AC_PASS" 2>&1 |
|
||||
tee -a "$LOGFILE")
|
||||
echo "${PROGRESS}" | tail -n 1
|
||||
|
||||
if [ $? -ne 0 ] || [[ "${PROGRESS}" =~ "Invalid" ]] ; then
|
||||
echo "Error with notarization. Exiting"
|
||||
break
|
||||
fi
|
||||
|
||||
if ! [[ "${PROGRESS}" =~ "in progress" ]]; then
|
||||
success=1
|
||||
break
|
||||
else
|
||||
echo "Not completed yet. Sleeping for 30 seconds."
|
||||
fi
|
||||
sleep 30
|
||||
done
|
||||
|
||||
if [ $success -eq 1 ] ; then
|
||||
if test "$ext" = "zip"; then
|
||||
TMPDIR=$(mktemp -d)
|
||||
echo "Extracting to $TMPDIR"
|
||||
@@ -37,9 +91,9 @@ for INPUT in "$@"; do
|
||||
cd "$(dirname "$STAPLE_TARGET")"
|
||||
zip -r -q "$INPUT_FULL" $(basename "$STAPLE_TARGET")
|
||||
fi
|
||||
echo "Processed $INPUT"
|
||||
fi
|
||||
echo "Processed $INPUT"
|
||||
|
||||
if test "$ext" = "zip"; then
|
||||
spctl -a -v "$STAPLE_TARGET"
|
||||
fi
|
||||
done
|
||||
if test "$ext" = "zip"; then
|
||||
spctl -a -v "$STAPLE_TARGET"
|
||||
fi
|
||||
|
||||
@@ -17,9 +17,10 @@ set -x
|
||||
#Exit on error
|
||||
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.
|
||||
MAC_CODESIGN_ID=${MAC_CODESIGN_ID:--}
|
||||
MAC_PRODUCTSIGN_ID=${MAC_PRODUCTSIGN_ID:--}
|
||||
|
||||
PKGDIR=$(mktemp -d)
|
||||
|
||||
@@ -27,17 +28,12 @@ SRC_DIR=$PWD
|
||||
OUTPUT_PATH=${FISH_ARTEFACT_PATH:-~/fish_built}
|
||||
|
||||
mkdir -p "$PKGDIR/build" "$PKGDIR/root" "$PKGDIR/intermediates" "$PKGDIR/dst"
|
||||
|
||||
# Pass FISH_USE_SYSTEM_PCRE2=OFF because a system PCRE2 on macOS will not be signed by fish,
|
||||
# and will probably not be built universal, so the package will fail to validate/run on other systems.
|
||||
{ cd "$PKGDIR/build" && cmake -DMAC_INJECT_GET_TASK_ALLOW=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo -DWITH_GETTEXT=OFF -DFISH_USE_SYSTEM_PCRE2=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"
|
||||
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"
|
||||
|
||||
# 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 -rf "$PKGDIR"
|
||||
rm -r "$PKGDIR"
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<installer-gui-script minSpecVersion="1">
|
||||
<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"/>
|
||||
<pkg-ref id="com.ridiculousfish.fish-shell-pkg"/>
|
||||
<options hostArchitectures="arm64,x86_64" rootVolumeOnly="true"/>
|
||||
<options customize="never" require-scripts="true"/>
|
||||
<options customize="never" require-scripts="false"/>
|
||||
<choices-outline>
|
||||
<line choice="default">
|
||||
<line choice="com.ridiculousfish.fish-shell-pkg"/>
|
||||
|
||||
@@ -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>
|
||||
26
build_tools/osx_package_resources/welcome.rtf
Normal file
26
build_tools/osx_package_resources/welcome.rtf
Normal 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!\
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh -x
|
||||
|
||||
./add-shell ${DSTVOLUME}usr/local/bin/fish
|
||||
./add-shell /usr/local/bin/fish > /tmp/fish_postinstall_output.log
|
||||
|
||||
@@ -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"
|
||||
@@ -26,40 +26,29 @@ import pexpect
|
||||
# Default timeout for failing to match.
|
||||
TIMEOUT_SECS = 5
|
||||
|
||||
UNEXPECTED_SUCCESS = object()
|
||||
|
||||
|
||||
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(
|
||||
r"""(?:\r\n?|^) # beginning of line
|
||||
(?:\x1b[\d\[KB(m]*)* # optional colors
|
||||
(?:\[.\]\ )? # optional vi mode prompt
|
||||
"""
|
||||
+ (r"prompt\ %d>" % counter) # prompt with counter
|
||||
+ r"""
|
||||
(?:\x1b[\d\[KB(m]*)* # optional colors
|
||||
""",
|
||||
+ (r"prompt\ %d>" % counter), # prompt with counter
|
||||
re.VERBOSE,
|
||||
)
|
||||
|
||||
|
||||
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())
|
||||
for f in callstack:
|
||||
# Skip call sites from this file.
|
||||
if inspect.getmodule(f.frame) is Message.MODULE:
|
||||
continue
|
||||
# Skip functions which have a truthy callsite_skip attribute.
|
||||
if getattr(f.function, "callsite_skip", False):
|
||||
continue
|
||||
return (os.path.basename(f.filename), f.lineno, f.code_context)
|
||||
if inspect.getmodule(f.frame) is not Message.MODULE:
|
||||
return (os.path.basename(f.filename), f.lineno, f.code_context)
|
||||
return ("Unknown", -1, "")
|
||||
|
||||
|
||||
def escape(s):
|
||||
"""Escape the string 's' to make it human-understandable."""
|
||||
""" Escape the string 's' to make it human-understandable. """
|
||||
res = []
|
||||
for c in s:
|
||||
if c == "\n":
|
||||
@@ -76,19 +65,17 @@ def escape(s):
|
||||
|
||||
|
||||
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):
|
||||
return "EOF"
|
||||
elif isinstance(err, pexpect.TIMEOUT):
|
||||
return "timeout"
|
||||
elif err is UNEXPECTED_SUCCESS:
|
||||
return "unexpected success"
|
||||
else:
|
||||
return "unknown error"
|
||||
|
||||
|
||||
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:
|
||||
dir: the message direction, either DIR_INPUT or DIR_OUTPUT
|
||||
@@ -106,7 +93,7 @@ class Message(object):
|
||||
MODULE = sys.modules[__name__]
|
||||
|
||||
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.filename, self.lineno, _ = get_callsite()
|
||||
self.text = text
|
||||
@@ -114,17 +101,17 @@ class Message(object):
|
||||
|
||||
@staticmethod
|
||||
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)
|
||||
|
||||
@staticmethod
|
||||
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)
|
||||
|
||||
|
||||
class SpawnedProc(object):
|
||||
"""A process, talking to our ptty. This wraps pexpect.spawn.
|
||||
""" A process, talking to our ptty. This wraps pexpect.spawn.
|
||||
|
||||
Attributes:
|
||||
colorize: whether error messages should have ANSI color escapes
|
||||
@@ -135,41 +122,37 @@ class SpawnedProc(object):
|
||||
function to ensure that each printed prompt is distinct.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, name="fish", timeout=TIMEOUT_SECS, env=os.environ.copy(), **kwargs
|
||||
):
|
||||
"""Construct from a name, timeout, and environment.
|
||||
def __init__(self, name="fish", timeout=TIMEOUT_SECS, env=os.environ.copy()):
|
||||
""" Construct from a name, timeout, and environment.
|
||||
|
||||
Args:
|
||||
name: the name of the executable to launch, as a key into the
|
||||
environment dictionary. By default this is 'fish' but may be
|
||||
other executables.
|
||||
timeout: A timeout to pass to pexpect. This indicates how long to wait
|
||||
before giving up on some expected output.
|
||||
env: a string->string dictionary, describing the environment variables.
|
||||
Args:
|
||||
name: the name of the executable to launch, as a key into the
|
||||
environment dictionary. By default this is 'fish' but may be
|
||||
other executables.
|
||||
timeout: A timeout to pass to pexpect. This indicates how long to wait
|
||||
before giving up on some expected output.
|
||||
env: a string->string dictionary, describing the environment variables.
|
||||
"""
|
||||
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)
|
||||
self.colorize = sys.stdout.isatty() or env.get("FISH_FORCE_COLOR", "0") == "1"
|
||||
self.colorize = sys.stdout.isatty()
|
||||
self.messages = []
|
||||
self.start_time = None
|
||||
self.spawn = pexpect.spawn(
|
||||
exe_path, env=env, encoding="utf-8", timeout=timeout, **kwargs
|
||||
)
|
||||
self.spawn = pexpect.spawn(exe_path, env=env, encoding="utf-8", timeout=timeout)
|
||||
self.spawn.delaybeforesend = None
|
||||
self.prompt_counter = 0
|
||||
self.prompt_counter = 1
|
||||
|
||||
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()
|
||||
if not self.start_time:
|
||||
self.start_time = now
|
||||
return now - self.start_time
|
||||
|
||||
def send(self, s):
|
||||
"""Cover over pexpect.spawn.send().
|
||||
Send the given string to the tty, returning the number of bytes written.
|
||||
""" Cover over pexpect.spawn.send().
|
||||
Send the given string to the tty, returning the number of bytes written.
|
||||
"""
|
||||
res = self.spawn.send(s)
|
||||
when = self.time_since_first_message()
|
||||
@@ -177,74 +160,61 @@ class SpawnedProc(object):
|
||||
return res
|
||||
|
||||
def sendline(self, s):
|
||||
"""Cover over pexpect.spawn.sendline().
|
||||
Send the given string + linesep to the tty, returning the number of bytes written.
|
||||
""" Cover over pexpect.spawn.sendline().
|
||||
Send the given string + linesep to the tty, returning the number of bytes written.
|
||||
"""
|
||||
return self.send(s + os.linesep)
|
||||
|
||||
def expect_re(self, pat, pat_desc=None, unmatched=None, shouldfail=False, **kwargs):
|
||||
"""Cover over pexpect.spawn.expect().
|
||||
Consume all "new" output of self.spawn until the given pattern is matched, or
|
||||
the timeout is reached.
|
||||
Note that output between the current position and the location of the match is
|
||||
consumed as well.
|
||||
The pattern is typically a regular expression in string form, but may also be
|
||||
any of the types accepted by pexpect.spawn.expect().
|
||||
If the 'unmatched' parameter is given, it is printed as part of the error message
|
||||
of any failure.
|
||||
On failure, this prints an error and exits.
|
||||
def expect_re(self, pat, pat_desc=None, unmatched=None, **kwargs):
|
||||
""" Cover over pexpect.spawn.expect().
|
||||
Consume all "new" output of self.spawn until the given pattern is matched, or
|
||||
the timeout is reached.
|
||||
Note that output between the current position and the location of the match is
|
||||
consumed as well.
|
||||
The pattern is typically a regular expression in string form, but may also be
|
||||
any of the types accepted by pexpect.spawn.expect().
|
||||
If the 'unmatched' parameter is given, it is printed as part of the error message
|
||||
of any failure.
|
||||
On failure, this prints an error and exits.
|
||||
"""
|
||||
try:
|
||||
self.spawn.expect(pat, **kwargs)
|
||||
res = self.spawn.expect(pat, **kwargs)
|
||||
when = self.time_since_first_message()
|
||||
self.messages.append(
|
||||
Message.received_output(self.spawn.match.group(), when)
|
||||
)
|
||||
# When a match is found,
|
||||
# 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
|
||||
return res
|
||||
except pexpect.ExceptionPexpect as err:
|
||||
if shouldfail:
|
||||
return True
|
||||
if not pat_desc:
|
||||
pat_desc = str(pat)
|
||||
self.report_exception_and_exit(pat_desc, unmatched, err)
|
||||
|
||||
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)
|
||||
|
||||
def expect_prompt(self, *args, increment=True, **kwargs):
|
||||
"""Convenience function which matches some text and then a prompt.
|
||||
Match the given positional arguments as expect_re, and then look
|
||||
for a prompt.
|
||||
If increment is set, then this should be a new prompt and the prompt counter
|
||||
should be bumped; otherwise this is not a new prompt.
|
||||
Returns None on success, and exits on failure.
|
||||
Example:
|
||||
sp.sendline("echo hello world")
|
||||
sp.expect_prompt("hello world")
|
||||
def expect_prompt(self, *args, **kwargs):
|
||||
""" Convenience function which matches some text and then a prompt.
|
||||
Match the given positional arguments as expect_re, and then look
|
||||
for a prompt, bumping the prompt counter.
|
||||
Returns None on success, and exits on failure.
|
||||
Example:
|
||||
sp.sendline("echo hello world")
|
||||
sp.expect_prompt("hello world")
|
||||
"""
|
||||
if args:
|
||||
self.expect_re(*args, **kwargs)
|
||||
if increment:
|
||||
self.prompt_counter += 1
|
||||
self.expect_re(
|
||||
get_prompt_re(self.prompt_counter),
|
||||
pat_desc="prompt %d" % self.prompt_counter,
|
||||
)
|
||||
self.prompt_counter += 1
|
||||
|
||||
def report_exception_and_exit(self, pat, unmatched, err):
|
||||
"""Things have gone badly.
|
||||
We have an exception 'err', some pexpect.ExceptionPexpect.
|
||||
Report it to stdout, along with the offending call site.
|
||||
If 'unmatched' is set, print it to stdout.
|
||||
""" Things have gone badly.
|
||||
We have an exception 'err', some pexpect.ExceptionPexpect.
|
||||
Report it to stdout, along with the offending call site.
|
||||
If 'unmatched' is set, print it to stdout.
|
||||
"""
|
||||
colors = self.colors()
|
||||
failtype = pexpect_error_type(err)
|
||||
@@ -273,18 +243,23 @@ class SpawnedProc(object):
|
||||
print("{CYAN}Escaped buffer:{RESET}".format(**colors))
|
||||
print(escape(self.spawn.before))
|
||||
print("")
|
||||
print("{CYAN}When written to the tty, this looks like:{RESET}".format(**colors))
|
||||
print("{CYAN}<-------{RESET}".format(**colors))
|
||||
sys.stdout.write(self.spawn.before)
|
||||
sys.stdout.flush()
|
||||
print("{RESET}\n{CYAN}------->{RESET}".format(**colors))
|
||||
if sys.stdout.isatty():
|
||||
print(
|
||||
"{CYAN}When written to the tty, this looks like:{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("")
|
||||
|
||||
# Show the last 10 messages.
|
||||
print("Last 10 messages:")
|
||||
# Show the last 5 messages.
|
||||
print("Last 5 messages:")
|
||||
delta = None
|
||||
for m in self.messages[-10:]:
|
||||
for m in self.messages[-5:]:
|
||||
etext = escape(m.text)
|
||||
timestamp = m.when * 1000.0
|
||||
# Use relative timestamps and add a sign.
|
||||
@@ -296,6 +271,7 @@ class SpawnedProc(object):
|
||||
else:
|
||||
timestampstr = "{timestamp:10.2f} ms".format(timestamp=timestamp)
|
||||
delta = m.when * 1000.0
|
||||
dir = m.dir
|
||||
print(
|
||||
"{dir} {timestampstr} (Line {lineno}): {BOLD}{etext}{RESET}".format(
|
||||
dir=m.dir,
|
||||
@@ -310,14 +286,14 @@ class SpawnedProc(object):
|
||||
sys.exit(1)
|
||||
|
||||
def sleep(self, secs):
|
||||
"""Cover over time.sleep()."""
|
||||
""" Cover over time.sleep(). """
|
||||
time.sleep(secs)
|
||||
|
||||
def colors(self):
|
||||
"""Return a dictionary mapping color names to ANSI escapes"""
|
||||
""" Return a dictionary mapping color names to ANSI escapes """
|
||||
|
||||
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 {
|
||||
@@ -341,25 +317,3 @@ class SpawnedProc(object):
|
||||
"LIGHTCYAN": ansic(96),
|
||||
"WHITE": ansic(97),
|
||||
}
|
||||
|
||||
|
||||
def control(char: str) -> str:
|
||||
""" Returns the char sent when control is pressed along the given key. """
|
||||
assert len(char) == 1
|
||||
char = char.lower()
|
||||
if ord("a") <= ord(char) <= ord("z"):
|
||||
return chr(ord(char) - ord("a") + 1)
|
||||
return chr({
|
||||
"@": 0,
|
||||
"`": 0,
|
||||
"[": 27,
|
||||
"{": 27,
|
||||
"\\": 28,
|
||||
"|": 28,
|
||||
"]": 29,
|
||||
"}": 29,
|
||||
"^": 30,
|
||||
"~": 30,
|
||||
"_": 31,
|
||||
"?": 127,
|
||||
}[char])
|
||||
|
||||
@@ -23,15 +23,13 @@ if test $all = yes
|
||||
set -l files (git status --porcelain --short --untracked-files=all | sed -e 's/^ *[^ ]* *//')
|
||||
if set -q files[1]
|
||||
echo
|
||||
echo 'You have uncommitted changes. Are you sure you want to restyle?'
|
||||
read -P 'y/N? ' -n1 -l ans
|
||||
if not string match -qi "y" -- $ans
|
||||
exit 1
|
||||
end
|
||||
echo You have uncommitted changes. Cowardly refusing to restyle the entire code base.
|
||||
echo
|
||||
exit 1
|
||||
end
|
||||
set c_files src/*.h src/*.cpp src/*.c
|
||||
set fish_files share/**.fish
|
||||
set python_files {doc_src,share,tests}/**.py
|
||||
set fish_files (printf '%s\n' share/***.fish)
|
||||
set python_files **.py
|
||||
else
|
||||
# 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.
|
||||
@@ -74,20 +72,13 @@ if set -q c_files[1]
|
||||
else if type -q clang-format
|
||||
echo === Running "$red"clang-format"$normal"
|
||||
for file in $c_files
|
||||
if clang-format --dry-run -Werror $file
|
||||
# file was clean, remove it from the list
|
||||
set -e c_files[(contains -i $file $c_files)]
|
||||
end
|
||||
end
|
||||
if set -q c_files[1]
|
||||
printf "Reformat those %d files?\n" (count $c_files)
|
||||
read -P 'y/N? ' -n1 -l ans
|
||||
if string match -qi "y" -- $ans
|
||||
clang-format -i --verbose $c_files
|
||||
else if string match -qi "n" -- $ans
|
||||
echo Skipping
|
||||
else # like they ctrl-C'd or something.
|
||||
exit 1
|
||||
cp $file $file.new # preserves mode bits
|
||||
clang-format $file >$file.new
|
||||
if cmp --quiet $file $file.new
|
||||
rm $file.new
|
||||
else
|
||||
echo $file was NOT correctly formatted
|
||||
mv $file.new $file
|
||||
end
|
||||
end
|
||||
else
|
||||
|
||||
3
build_tools/ubsan.blacklist
Normal file
3
build_tools/ubsan.blacklist
Normal 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
|
||||
@@ -56,9 +56,9 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
|
||||
endif()
|
||||
|
||||
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")
|
||||
set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckIncludeFiles/${VARIABLE}.cpp)
|
||||
set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckIncludeFiles/${var}.cpp)
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown language:\n ${_lang}\nSupported languages: C, CXX.\n")
|
||||
endif()
|
||||
|
||||
@@ -4,60 +4,15 @@
|
||||
# `wcstod_l` is a GNU-extension, sometimes hidden behind GNU-related defines.
|
||||
# This is the case for at least Cygwin and Newlib.
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE=1)
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(CMakePushCheckState)
|
||||
|
||||
if(APPLE)
|
||||
include(CheckCXXCompilerFlag)
|
||||
check_cxx_compiler_flag("-Werror=unguarded-availability" REQUIRES_UNGUARDED_AVAILABILITY)
|
||||
if(REQUIRES_UNGUARDED_AVAILABILITY)
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "-Werror=unguarded-availability")
|
||||
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()
|
||||
|
||||
# Defeat bogus warnings about missing field initializers for `var{}` initialization.
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS "-W")
|
||||
check_cxx_source_compiles("
|
||||
struct sr_t { int x; };
|
||||
int main(void) {
|
||||
sr_t sr{};
|
||||
return sr.x;
|
||||
}"
|
||||
EMPTY_VALUE_INIT_ACCEPTED
|
||||
FAIL_REGEX "-Wmissing-field-initializers"
|
||||
)
|
||||
if (NOT EMPTY_VALUE_INIT_ACCEPTED)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers")
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
|
||||
# Disable static destructors if we can.
|
||||
check_cxx_compiler_flag("-fno-c++-static-destructors" DISABLE_STATIC_DESTRUCTORS)
|
||||
if (DISABLE_STATIC_DESTRUCTORS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-c++-static-destructors")
|
||||
endif()
|
||||
|
||||
|
||||
# Try using CMake's own logic to locate curses/ncurses
|
||||
find_package(Curses)
|
||||
if(NOT ${CURSES_FOUND})
|
||||
@@ -70,25 +25,13 @@ if(NOT ${CURSES_FOUND})
|
||||
set(CURSES_CURSES_LIBRARY ${CURSES_LIBRARIES})
|
||||
set(CURSES_LIBRARY ${CURSES_LIBRARIES})
|
||||
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})
|
||||
else()
|
||||
# on NetBSD, libtinfo has a longer name (libterminfo)
|
||||
find_library(CURSES_TINFO terminfo)
|
||||
if (CURSES_TINFO)
|
||||
set(CURSES_LIBRARY ${CURSES_LIBRARY} ${CURSES_TINFO})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Get threads.
|
||||
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)
|
||||
|
||||
# Detect WSL. Does not match against native Windows/WIN32.
|
||||
@@ -105,26 +48,24 @@ include(CheckIncludeFiles)
|
||||
include(CheckStructHasMember)
|
||||
include(CheckCXXSourceCompiles)
|
||||
include(CheckTypeSize)
|
||||
include(CMakePushCheckState)
|
||||
check_cxx_symbol_exists(backtrace_symbols execinfo.h HAVE_BACKTRACE_SYMBOLS)
|
||||
|
||||
# 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(clock_gettime time.h HAVE_CLOCK_GETTIME)
|
||||
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_cxx_symbol_exists(dirfd "sys/types.h;dirent.h" HAVE_DIRFD)
|
||||
check_include_file_cxx(execinfo.h HAVE_EXECINFO_H)
|
||||
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(getpwent pwd.h HAVE_GETPWENT)
|
||||
check_cxx_symbol_exists(getrusage sys/resource.h HAVE_GETRUSAGE)
|
||||
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(lrand48_r stdlib.h HAVE_LRAND48_R)
|
||||
# mkostemp is in stdlib in glibc and FreeBSD, but unistd on macOS
|
||||
check_cxx_symbol_exists(mkostemp "stdlib.h;unistd.h" HAVE_MKOSTEMP)
|
||||
set(HAVE_CURSES_H ${CURSES_HAVE_CURSES_H})
|
||||
@@ -144,26 +85,27 @@ check_struct_has_member("struct stat" st_mtimespec.tv_nsec "sys/stat.h"
|
||||
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
|
||||
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/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)
|
||||
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(wcsdup wchar.h HAVE_WCSDUP)
|
||||
check_cxx_symbol_exists(wcslcpy wchar.h HAVE_WCSLCPY)
|
||||
check_cxx_symbol_exists(wcsncasecmp wchar.h HAVE_WCSNCASECMP)
|
||||
check_cxx_symbol_exists(wcsndup wchar.h HAVE_WCSNDUP)
|
||||
|
||||
# These are for compatibility with Solaris 10, which places the following
|
||||
# in the std namespace.
|
||||
if(NOT HAVE_WCSNCASECMP)
|
||||
check_cxx_symbol_exists(std::wcscasecmp wchar.h HAVE_STD__WCSCASECMP)
|
||||
endif()
|
||||
if(NOT HAVE_WCSDUP)
|
||||
check_cxx_symbol_exists(std::wcsdup wchar.h HAVE_STD__WCSDUP)
|
||||
endif()
|
||||
if(NOT HAVE_WCSNCASECMP)
|
||||
check_cxx_symbol_exists(std::wcsncasecmp wchar.h HAVE_STD__WCSNCASECMP)
|
||||
endif()
|
||||
|
||||
@@ -176,12 +118,13 @@ endif()
|
||||
list(APPEND WCSTOD_L_INCLUDES "wchar.h")
|
||||
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()
|
||||
check_struct_has_member("struct winsize" ws_row "termios.h;sys/ioctl.h" _HAVE_WINSIZE)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES termios.h sys/ioctl.h)
|
||||
check_type_size("struct winsize" STRUCT_WINSIZE LANGUAGE CXX)
|
||||
check_cxx_symbol_exists("TIOCGWINSZ" "termios.h;sys/ioctl.h" HAVE_TIOCGWINSZ)
|
||||
if(_HAVE_WINSIZE EQUAL 1 AND HAVE_TIOCGWINSZ EQUAL 1)
|
||||
if(STRUCT_WINSIZE GREATER -1 AND HAVE_TIOCGWINSZ EQUAL 1)
|
||||
set(HAVE_WINSIZE 1)
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
@@ -203,9 +146,9 @@ elseif(HAVE_NCURSES_TERM_H)
|
||||
set(TPARM_INCLUDES "${TPARM_INCLUDES}#include <ncurses/term.h>\n")
|
||||
endif()
|
||||
|
||||
# Solaris and X/Open-conforming systems have a fixed-args tparm
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CURSES_LIBRARY})
|
||||
# Solaris and X/Open-conforming systems have a fixed-args tparm
|
||||
check_cxx_source_compiles("
|
||||
#define TPARM_VARARGS
|
||||
${TPARM_INCLUDES}
|
||||
@@ -217,23 +160,6 @@ int main () {
|
||||
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)
|
||||
set(TPARM_VARARGS 1)
|
||||
else()
|
||||
@@ -273,36 +199,11 @@ int main () {
|
||||
check_cxx_source_compiles("
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
std::atomic<uint8_t> n8 (0);
|
||||
std::atomic<uint64_t> n64 (0);
|
||||
std::atomic<uint64_t> x;
|
||||
int main() {
|
||||
uint8_t i = n8.load(std::memory_order_relaxed);
|
||||
uint64_t j = n64.load(std::memory_order_relaxed);
|
||||
return std::atomic_is_lock_free(&n8)
|
||||
& std::atomic_is_lock_free(&n64);
|
||||
return x;
|
||||
}"
|
||||
LIBATOMIC_NOT_NEEDED)
|
||||
IF (NOT LIBATOMIC_NOT_NEEDED)
|
||||
set(ATOMIC_LIBRARY "atomic")
|
||||
endif()
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <sys/wait.h>
|
||||
|
||||
int main() {
|
||||
static_assert(WEXITSTATUS(0x007f) == 0x7f, \"This is our message we need to add because C++ is terrible\");
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
HAVE_WAITSTATUS_SIGNAL_RET)
|
||||
|
||||
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()
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ include(FeatureSummary)
|
||||
set(SPHINX_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/doc_src")
|
||||
set(SPHINX_ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/user_doc")
|
||||
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_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.
|
||||
add_custom_target(sphinx-docs
|
||||
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"
|
||||
${SPHINX_EXECUTABLE}
|
||||
-j auto
|
||||
-q -b html
|
||||
-c "${SPHINX_SRC_DIR}"
|
||||
-d "${SPHINX_ROOT_DIR}/.doctrees-html"
|
||||
-d "${SPHINX_CACHE_DIR}"
|
||||
"${SPHINX_SRC_DIR}"
|
||||
"${SPHINX_HTML_DIR}"
|
||||
DEPENDS ${SPHINX_SRC_DIR}/fish_indent_lexer.py fish_indent
|
||||
@@ -31,10 +33,9 @@ add_custom_target(sphinx-docs
|
||||
add_custom_target(sphinx-manpages
|
||||
env PATH="$<TARGET_FILE_DIR:fish_indent>:$$PATH"
|
||||
${SPHINX_EXECUTABLE}
|
||||
-j auto
|
||||
-q -b man
|
||||
-c "${SPHINX_SRC_DIR}"
|
||||
-d "${SPHINX_ROOT_DIR}/.doctrees-man"
|
||||
-d "${SPHINX_CACHE_DIR}"
|
||||
"${SPHINX_SRC_DIR}"
|
||||
# TODO: This only works if we only have section 1 manpages.
|
||||
"${SPHINX_MANPAGE_DIR}/man1"
|
||||
|
||||
@@ -14,8 +14,8 @@ set(bindir ${CMAKE_INSTALL_BINDIR})
|
||||
set(sysconfdir ${CMAKE_INSTALL_SYSCONFDIR})
|
||||
set(mandir ${CMAKE_INSTALL_MANDIR})
|
||||
|
||||
set(rel_datadir ${CMAKE_INSTALL_DATADIR})
|
||||
set(datadir ${CMAKE_INSTALL_FULL_DATADIR})
|
||||
file(RELATIVE_PATH rel_datadir ${CMAKE_INSTALL_PREFIX} ${datadir})
|
||||
|
||||
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/js
|
||||
${rel_datadir}/fish/tools/web_config/partials
|
||||
${rel_datadir}/fish/tools/web_config/sample_prompts
|
||||
${rel_datadir}/fish/tools/web_config/themes
|
||||
)
|
||||
${rel_datadir}/fish/tools/web_config/sample_prompts)
|
||||
|
||||
configure_file(share/__fish_build_paths.fish.in share/__fish_build_paths.fish)
|
||||
install(FILES share/config.fish
|
||||
@@ -112,7 +110,7 @@ add_custom_command(OUTPUT fish.pc
|
||||
COMMAND printf "Version: " >> fish.pc
|
||||
COMMAND sed 's/FISH_BUILD_VERSION=//\;s/\"//g' ${FBVF} >> fish.pc
|
||||
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)
|
||||
|
||||
@@ -149,7 +147,6 @@ install(DIRECTORY share/tools/web_config
|
||||
PATTERN "*.html"
|
||||
PATTERN "*.py"
|
||||
PATTERN "*.js"
|
||||
PATTERN "*.theme"
|
||||
PATTERN "*.fish")
|
||||
|
||||
# Building the man pages is optional: if Sphinx isn't installed, they're not built
|
||||
@@ -158,6 +155,8 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/user_doc/html/ # Trailing slash is
|
||||
DESTINATION ${docdir} OPTIONAL)
|
||||
install(FILES CHANGELOG.rst DESTINATION ${docdir})
|
||||
|
||||
install(FILES share/lynx.lss DESTINATION ${rel_datadir}/fish/)
|
||||
|
||||
# These files are built by cmake/gettext.cmake, but using GETTEXT_PROCESS_PO_FILES's
|
||||
# INSTALL_DESTINATION leads to them being installed as ${lang}.gmo, not fish.mo
|
||||
# The ${languages} array comes from cmake/gettext.cmake
|
||||
@@ -168,14 +167,13 @@ if(GETTEXT_FOUND)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if (NOT APPLE)
|
||||
install(FILES fish.desktop DESTINATION ${rel_datadir}/applications)
|
||||
install(FILES ${SPHINX_SRC_DIR}/python_docs_theme/static/fish.png DESTINATION ${rel_datadir}/pixmaps)
|
||||
endif()
|
||||
install(FILES fish.desktop DESTINATION ${rel_datadir}/applications)
|
||||
install(FILES fish.png DESTINATION ${rel_datadir}/pixmaps)
|
||||
|
||||
# Group install targets into a InstallTargets folder
|
||||
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)
|
||||
|
||||
# Make a target build_root that installs into the buildroot directory, for testing.
|
||||
|
||||
@@ -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.
|
||||
# '-' 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
|
||||
# on the 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)
|
||||
if((APPLE) AND (MAC_CODESIGN_ID))
|
||||
execute_process(COMMAND sw_vers "-productVersion" OUTPUT_VARIABLE OSX_VERSION)
|
||||
|
||||
@@ -73,6 +73,3 @@ add_custom_target(signed_fish_macapp
|
||||
$<TARGET_BUNDLE_DIR:fish_macapp>
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Group our targets in a folder.
|
||||
set_property(TARGET fish_macapp signed_fish_macapp PROPERTY FOLDER macapp)
|
||||
|
||||
@@ -28,50 +28,16 @@ else()
|
||||
endif()
|
||||
|
||||
set(FISH_USE_SYSTEM_PCRE2 ${USE_SYS_PCRE2_DEFAULT} CACHE BOOL
|
||||
"Use PCRE2 from the system, instead of fetching and building it")
|
||||
"Use PCRE2 from the system, instead of bundled with fish")
|
||||
|
||||
if(FISH_USE_SYSTEM_PCRE2)
|
||||
set(PCRE2_LIB "${SYS_PCRE2_LIB}")
|
||||
set(PCRE2_INCLUDE_DIR "${SYS_PCRE2_INCLUDE_DIR}")
|
||||
message(STATUS "Using system PCRE2 library ${PCRE2_INCLUDE_DIR}")
|
||||
else()
|
||||
include(FetchContent RESULT_VARIABLE HAVE_FetchContent)
|
||||
if (${HAVE_FetchContent} STREQUAL "NOTFOUND")
|
||||
message(FATAL_ERROR "Please install PCRE2 headers, or CMake >= 3.11 so I can download PCRE")
|
||||
endif()
|
||||
set(CMAKE_TLS_VERIFY true)
|
||||
set(PCRE2_REPO "https://github.com/PCRE2Project/pcre2.git")
|
||||
|
||||
message(STATUS "Fetching and configuring PCRE2 from ${PCRE2_REPO}")
|
||||
Set(FETCHCONTENT_QUIET FALSE)
|
||||
FetchContent_Declare(
|
||||
pcre2
|
||||
GIT_REPOSITORY ${PCRE2_REPO}
|
||||
GIT_TAG "72669190cb947f0cac1d038a8bb1820da59ef447" # tag: pcre2-10.36
|
||||
GIT_SHALLOW ON
|
||||
GIT_PROGRESS TRUE
|
||||
)
|
||||
# Don't try FetchContent_MakeAvailable, there's no way to add EXCLUDE_FROM_ALL
|
||||
# so we end up installing all of PCRE2 including its headers, man pages, etc.
|
||||
FetchContent_GetProperties(pcre2)
|
||||
if (NOT pcre2_POPULATED)
|
||||
# If GIT_WORK_TREE is set (by user or by git itself with e.g. git rebase), it
|
||||
# will override the git directory which CMake tries to apply in FetchContent_Populate,
|
||||
# resulting in a failed checkout.
|
||||
# Ensure it is not set.
|
||||
unset(ENV{GIT_WORK_TREE})
|
||||
unset(ENV{GIT_DIR})
|
||||
FetchContent_Populate(pcre2)
|
||||
add_subdirectory(${pcre2_SOURCE_DIR} ${pcre2_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
set(PCRE2_INCLUDE_DIR ${pcre2_BINARY_DIR})
|
||||
message(STATUS "Using bundled PCRE2 library")
|
||||
add_subdirectory(pcre2 EXCLUDE_FROM_ALL)
|
||||
set(PCRE2_INCLUDE_DIR ${CMAKE_BINARY_DIR}/pcre2)
|
||||
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)
|
||||
include_directories(${PCRE2_INCLUDE_DIR})
|
||||
|
||||
@@ -1,56 +1,4 @@
|
||||
# This adds ctest support to the project
|
||||
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
|
||||
# Define fish_tests.
|
||||
add_executable(fish_tests EXCLUDE_FROM_ALL
|
||||
src/fish_tests.cpp)
|
||||
fish_link_deps_and_sign(fish_tests)
|
||||
@@ -58,43 +6,24 @@ fish_link_deps_and_sign(fish_tests)
|
||||
# The "test" directory.
|
||||
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.
|
||||
set(TEST_INSTALL_DIR ${TEST_DIR}/buildroot)
|
||||
|
||||
# The directory where the tests expect to find the fish root (./bin, etc)
|
||||
set(TEST_ROOT_DIR ${TEST_DIR}/root)
|
||||
|
||||
# Copy needed directories for out-of-tree builds
|
||||
if(NOT FISH_IN_TREE_BUILD)
|
||||
add_custom_target(funcs_dir)
|
||||
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)
|
||||
# Copy tests files.
|
||||
file(GLOB TESTS_FILES tests/*)
|
||||
add_custom_target(tests_dir DEPENDS tests)
|
||||
|
||||
add_custom_target(tests_dir DEPENDS tests)
|
||||
add_custom_command(TARGET tests_dir
|
||||
if(NOT FISH_IN_TREE_BUILD)
|
||||
add_custom_command(TARGET tests_dir
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_SOURCE_DIR}/tests/ ${CMAKE_BINARY_DIR}/tests/
|
||||
COMMENT "Copying test files to binary dir"
|
||||
VERBATIM)
|
||||
|
||||
add_dependencies(fish_tests tests_dir funcs_dir)
|
||||
add_dependencies(fish_tests tests_dir)
|
||||
endif()
|
||||
|
||||
# Copy littlecheck.py
|
||||
@@ -103,75 +32,94 @@ configure_file(build_tools/littlecheck.py littlecheck.py COPYONLY)
|
||||
# Copy pexpect_helper.py
|
||||
configure_file(build_tools/pexpect_helper.py pexpect_helper.py COPYONLY)
|
||||
|
||||
# Suppress generating Xcode schemes for all tests, there's too many.
|
||||
set(CMAKE_XCODE_GENERATE_SCHEME 0)
|
||||
|
||||
# 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()
|
||||
|
||||
# Make the directory in which to run tests.
|
||||
# Also symlink fish to where the tests expect it to be.
|
||||
# Lastly put fish_test_helper there too.
|
||||
add_custom_target(tests_buildroot_target
|
||||
# Make the directory in which to run tests:
|
||||
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
|
||||
# Put fish_test_helper there too:
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/fish_test_helper
|
||||
${TEST_INSTALL_DIR}/${CMAKE_INSTALL_PREFIX}/bin
|
||||
# Also symlink fish to where the tests expect it to be:
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
${TEST_INSTALL_DIR}/${CMAKE_INSTALL_PREFIX}
|
||||
${TEST_ROOT_DIR}
|
||||
DEPENDS fish fish_test_helper)
|
||||
|
||||
# CMake less than 3.9.0 "fully supports" setting an exit code to denote a skipped test, but then
|
||||
# it just goes ahead and reports it as failed. Really?
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.9.0")
|
||||
set(CMAKE_SKIPPED_HACK "env" "CMAKE_SKIPPED_HACK=1")
|
||||
if(NOT FISH_IN_TREE_BUILD)
|
||||
# We need to symlink share/functions for the tests.
|
||||
# This should be simplified.
|
||||
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()
|
||||
set(CMAKE_SKIPPED_HACK)
|
||||
add_custom_target(symlink_functions)
|
||||
endif()
|
||||
|
||||
foreach(LTEST ${LOW_LEVEL_TESTS})
|
||||
add_test(
|
||||
NAME ${LTEST}
|
||||
COMMAND sh ${CMAKE_CURRENT_BINARY_DIR}/tests/test_env.sh
|
||||
${CMAKE_BINARY_DIR}/fish_tests ${LTEST}
|
||||
# Prep the environment for running the unit tests.
|
||||
add_custom_target(test_prep
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${TEST_DIR}/data
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${TEST_DIR}/home
|
||||
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}
|
||||
)
|
||||
set_tests_properties(${LTEST} PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE})
|
||||
add_test_target("${LTEST}")
|
||||
endforeach(LTEST)
|
||||
DEPENDS fish_tests
|
||||
USES_TERMINAL)
|
||||
|
||||
FILE(GLOB FISH_CHECKS CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/tests/checks/*.fish)
|
||||
foreach(CHECK ${FISH_CHECKS})
|
||||
get_filename_component(CHECK_NAME ${CHECK} NAME)
|
||||
get_filename_component(CHECK ${CHECK} NAME_WE)
|
||||
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})
|
||||
set_tests_properties(${CHECK_NAME} PROPERTIES ENVIRONMENT FISH_FORCE_COLOR=1)
|
||||
add_test_target("${CHECK_NAME}")
|
||||
endforeach(CHECK)
|
||||
add_custom_target(${TESTTYPE}_fishscript
|
||||
COMMAND cd tests && ${TEST_ROOT_DIR}/bin/fish test.fish
|
||||
DEPENDS test_prep
|
||||
USES_TERMINAL)
|
||||
|
||||
FILE(GLOB PEXPECTS CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/tests/pexpects/*.py)
|
||||
foreach(PEXPECT ${PEXPECTS})
|
||||
get_filename_component(PEXPECT ${PEXPECT} NAME)
|
||||
add_test(NAME ${PEXPECT}
|
||||
COMMAND ${CMAKE_SKIPPED_HACK} sh ${CMAKE_CURRENT_BINARY_DIR}/tests/test_driver.sh
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/interactive.fish ${PEXPECT}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tests
|
||||
)
|
||||
set_tests_properties(${PEXPECT} PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE})
|
||||
set_tests_properties(${PEXPECT} PROPERTIES ENVIRONMENT FISH_FORCE_COLOR=1)
|
||||
add_test_target("${PEXPECT}")
|
||||
endforeach(PEXPECT)
|
||||
add_custom_target(${TESTTYPE}_interactive
|
||||
COMMAND cd tests && ${TEST_ROOT_DIR}/bin/fish interactive.fish
|
||||
DEPENDS test_prep
|
||||
USES_TERMINAL)
|
||||
endforeach(TESTTYPE)
|
||||
|
||||
# Now add a dependency chain between the serial versions.
|
||||
# This ensures they run in order.
|
||||
add_dependencies(serial_test_fishscript serial_test_low_level)
|
||||
add_dependencies(serial_test_interactive serial_test_fishscript)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,39 +1,26 @@
|
||||
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)
|
||||
|
||||
option(WITH_GETTEXT "translate messages if gettext is available" ON)
|
||||
if(WITH_GETTEXT)
|
||||
if(APPLE)
|
||||
# Fix for https://github.com/fish-shell/fish-shell/issues/5244
|
||||
# via https://gitlab.kitware.com/cmake/cmake/-/issues/18921
|
||||
set(CMAKE_FIND_FRAMEWORK_OLD ${CMAKE_FIND_FRAMEWORK})
|
||||
set(CMAKE_FIND_FRAMEWORK NEVER)
|
||||
endif()
|
||||
find_package(Intl QUIET)
|
||||
find_package(Gettext)
|
||||
if(GETTEXT_FOUND)
|
||||
set(HAVE_GETTEXT 1)
|
||||
include_directories(${Intl_INCLUDE_DIR})
|
||||
endif()
|
||||
if(APPLE)
|
||||
set(CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK_OLD})
|
||||
unset(CMAKE_FIND_FRAMEWORK_OLD)
|
||||
endif()
|
||||
endif()
|
||||
add_feature_info(gettext GETTEXT_FOUND "translate messages with gettext")
|
||||
|
||||
# Define translations
|
||||
if(GETTEXT_FOUND)
|
||||
# Group pofile targets into their own folder, as there's a lot of them.
|
||||
set(CMAKE_FOLDER pofiles)
|
||||
foreach(lang ${languages})
|
||||
# Our translations aren't set up entirely as CMake expects, so installation is done in
|
||||
# cmake/Install.cmake instead of using INSTALL_DESTINATION
|
||||
gettext_process_po_files(${lang} ALL
|
||||
PO_FILES po/${lang}.po)
|
||||
endforeach()
|
||||
set(CMAKE_FOLDER)
|
||||
endif()
|
||||
|
||||
cmake_push_check_state()
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
/* Define to 1 if compiled on WSL */
|
||||
#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. */
|
||||
#cmakedefine HAVE_CTERMID_R 1
|
||||
|
||||
@@ -19,6 +22,15 @@
|
||||
/* Define to 1 if you have the `flock' function. */
|
||||
#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. */
|
||||
#cmakedefine HAVE_GETIFADDRS 1
|
||||
|
||||
/* Define to 1 if you have the `getpwent' function. */
|
||||
#cmakedefine HAVE_GETPWENT 1
|
||||
|
||||
@@ -31,6 +43,9 @@
|
||||
/* Define to 1 if you have the `killpg' function. */
|
||||
#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. */
|
||||
#cmakedefine HAVE_MKOSTEMP 1
|
||||
|
||||
@@ -46,12 +61,6 @@
|
||||
/* Define to 1 if you have the <ncurses/term.h> header file. */
|
||||
#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. */
|
||||
#cmakedefine HAVE_SIGINFO_H 1
|
||||
|
||||
@@ -61,6 +70,9 @@
|
||||
/* Define to 1 if you have the `std::wcscasecmp' function. */
|
||||
#cmakedefine HAVE_STD__WCSCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `std::wcsdup' function. */
|
||||
#cmakedefine HAVE_STD__WCSDUP 1
|
||||
|
||||
/* Define to 1 if you have the `std::wcsncasecmp' function. */
|
||||
#cmakedefine HAVE_STD__WCSNCASECMP 1
|
||||
|
||||
@@ -76,6 +88,9 @@
|
||||
/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
|
||||
#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. */
|
||||
#cmakedefine HAVE_SYS_IOCTL_H 1
|
||||
|
||||
@@ -85,21 +100,30 @@
|
||||
/* Define to 1 if you have the <sys/sysctl.h> header file. */
|
||||
#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. */
|
||||
#cmakedefine HAVE_TERM_H 1
|
||||
|
||||
/* Define to 1 if you have the `wcscasecmp' function. */
|
||||
#cmakedefine HAVE_WCSCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `wcsdup' function. */
|
||||
#cmakedefine HAVE_WCSDUP 1
|
||||
|
||||
/* Define to 1 if you have the `wcslcpy' function. */
|
||||
#cmakedefine HAVE_WCSLCPY 1
|
||||
|
||||
/* Define to 1 if you have the `wcsncasecmp' function. */
|
||||
#cmakedefine HAVE_WCSNCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `wcsndup' function. */
|
||||
#cmakedefine HAVE_WCSNDUP 1
|
||||
|
||||
/* Define to 1 if you have the `wcstod_l' function. */
|
||||
#cmakedefine HAVE_WCSTOD_L 1
|
||||
|
||||
/* Define to 1 if the status that wait returns and WEXITSTATUS expects is signal and then ret instead of the other way around. */
|
||||
#cmakedefine HAVE_WAITSTATUS_SIGNAL_RET 1
|
||||
|
||||
/* Define to 1 if the winsize struct and TIOCGWINSZ macro exist */
|
||||
#cmakedefine HAVE_WINSIZE 1
|
||||
|
||||
@@ -109,8 +133,8 @@
|
||||
/* Define to 1 if std::make_unique is available. */
|
||||
#cmakedefine HAVE_STD__MAKE_UNIQUE 1
|
||||
|
||||
/* Define to use clock_gettime and futimens to hack around Linux mtime issue */
|
||||
#cmakedefine UVAR_FILE_SET_MTIME_HACK 1
|
||||
/* Define to 1 if the _sys_errs array is available. */
|
||||
#cmakedefine HAVE__SYS__ERRS 1
|
||||
|
||||
/* Define to 1 to disable ncurses macros that conflict with the STL */
|
||||
#define NCURSES_NOMACROS 1
|
||||
@@ -127,9 +151,6 @@
|
||||
/* Use a variadic tparm on NetBSD curses. */
|
||||
#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. */
|
||||
#cmakedefine TPARM_SOLARIS_KLUDGE 1
|
||||
|
||||
@@ -144,18 +165,11 @@
|
||||
/* Define if xlocale.h is required for locale_t or wide character support */
|
||||
#cmakedefine HAVE_XLOCALE_H 1
|
||||
|
||||
/* Define if uselocale is available */
|
||||
#cmakedefine HAVE_USELOCALE 1
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#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
|
||||
#ifndef __warn_unused
|
||||
#define __warn_unused __attribute__ ((warn_unused_result))
|
||||
@@ -163,26 +177,3 @@
|
||||
#else
|
||||
#define __warn_unused
|
||||
#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
2
debian/compat
vendored
@@ -1 +1 @@
|
||||
10
|
||||
9
|
||||
|
||||
34
debian/control
vendored
34
debian/control
vendored
@@ -3,10 +3,10 @@ Section: shells
|
||||
Priority: optional
|
||||
Maintainer: ridiculous_fish <corydoras@ridiculousfish.com>
|
||||
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.20160115), libncurses5-dev, cmake (>= 3.5.0), gettext, libpcre2-dev,
|
||||
Build-Depends: debhelper (>= 9.20151004), libncurses5-dev, cmake (>= 3.2.0), gettext,
|
||||
# Test dependencies
|
||||
locales-all, python3
|
||||
# When libpcre2-dev is available on all supported Debian versions, add a dependency on that.
|
||||
Standards-Version: 4.1.5
|
||||
Homepage: https://fishshell.com/
|
||||
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
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, passwd (>= 4.0.3-10), gettext-base, man-db,
|
||||
procps, python3 (>=3.5)
|
||||
Conflicts: fish-common
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, fish-common (= ${source:Version}), passwd (>= 4.0.3-10), gettext-base, man-db
|
||||
Recommends: xsel (>=1.2.0)
|
||||
Suggests: xdg-utils
|
||||
Description: 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.
|
||||
|
||||
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.
|
||||
|
||||
0
debian/docs → debian/fish-common.docs
vendored
0
debian/docs → debian/fish-common.docs
vendored
2
debian/fish-common.install
vendored
Normal file
2
debian/fish-common.install
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
debian/tmp/etc
|
||||
debian/tmp/usr/share
|
||||
4
debian/fish-common.lintian-overrides
vendored
Normal file
4
debian/fish-common.lintian-overrides
vendored
Normal 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
1
debian/fish.install
vendored
Normal file
@@ -0,0 +1 @@
|
||||
debian/tmp/usr/bin
|
||||
0
debian/postinst → debian/fish.postinst
vendored
0
debian/postinst → debian/fish.postinst
vendored
37
debian/fish.postrm
vendored
Normal file
37
debian/fish.postrm
vendored
Normal 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
|
||||
0
debian/prerm → debian/fish.prerm
vendored
0
debian/prerm → debian/fish.prerm
vendored
4
debian/lintian-overrides
vendored
4
debian/lintian-overrides
vendored
@@ -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
13
debian/rules
vendored
@@ -9,9 +9,12 @@ export DH_VERBOSE=1
|
||||
|
||||
# Setting the build system is still required, because otherwise the GNUmakefile gets picked up
|
||||
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
|
||||
# Build fish_tests/tests_buildroot_target by hand (remove this once Ubuntu Xenial is out of support)
|
||||
override_dh_auto_build:
|
||||
dh_auto_build -- all fish_tests tests_buildroot_target
|
||||
override_dh_installdocs:
|
||||
dh_installdocs --link-doc=fish
|
||||
|
||||
# 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Release notes
|
||||
#############
|
||||
CHANGELOG
|
||||
#########
|
||||
|
||||
.. include:: ../CHANGELOG.rst
|
||||
10
doc_src/_static/custom.css
Normal file
10
doc_src/_static/custom.css
Normal 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;
|
||||
}
|
||||
84
doc_src/_static/pygments.css
Normal file
84
doc_src/_static/pygments.css
Normal file
@@ -0,0 +1,84 @@
|
||||
@import "nature.css";
|
||||
|
||||
.highlight .hll { background-color: #ffffcc }
|
||||
.highlight { background: #f8f8f8; }
|
||||
.highlight .c { color: #8f5902; } /* Comment */
|
||||
.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */
|
||||
.highlight .g { color: #000000 } /* Generic */
|
||||
.highlight .k { color: #204a87; font-weight: bold } /* Keyword */
|
||||
.highlight .l { color: #000000 } /* Literal */
|
||||
.highlight .n { color: #000000 } /* Name */
|
||||
.highlight .o { color: #00a6b2; } /* Operator */
|
||||
.highlight .x { color: #000000 } /* Other */
|
||||
.highlight .p { color: #00afff; } /* Punctuation */
|
||||
.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */
|
||||
.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */
|
||||
.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */
|
||||
.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */
|
||||
.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */
|
||||
.highlight .gd { color: #a40000 } /* Generic.Deleted */
|
||||
.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #ef2929 } /* Generic.Error */
|
||||
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.highlight .gi { color: #00A000 } /* Generic.Inserted */
|
||||
.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 .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */
|
||||
.highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */
|
||||
.highlight .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */
|
||||
.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 .s { color: #4e9a06 } /* Literal.String */
|
||||
.highlight .na { color: #c4a000 } /* Name.Attribute */
|
||||
.highlight .nb { color: #204a87 } /* Name.Builtin */
|
||||
.highlight .nc { color: #000000 } /* Name.Class */
|
||||
.highlight .no { color: #00afff } /* Name.Constant */
|
||||
.highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */
|
||||
.highlight .ni { color: #ce5c00 } /* Name.Entity */
|
||||
.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */
|
||||
.highlight .nf { color: #005fd7 } /* Name.Function */
|
||||
.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 .nv { color: #000000 } /* Name.Variable */
|
||||
.highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */
|
||||
.highlight .w { color: #f8f8f8; } /* Text.Whitespace */
|
||||
.highlight .mb { color: #0000cf; font-weight: bold } /* Literal.Number.Bin */
|
||||
.highlight .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */
|
||||
.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */
|
||||
.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #4e9a06 } /* Literal.String.Char */
|
||||
.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */
|
||||
.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #999900 } /* Literal.String.Double */
|
||||
.highlight .se { color: #00a6b2 } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #4e9a06 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #999900 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */
|
||||
.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 */
|
||||
.purple { color: #551a8b }
|
||||
.yellow { color: #FFFF00 }
|
||||
.red { color: #FF0000 }
|
||||
.gray { color: #555555 }
|
||||
.underline { text-decoration: underline }
|
||||
@@ -6,9 +6,9 @@ _ - call fish's translations
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
_ STRING
|
||||
_ STRING...
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
-------
|
||||
|
||||
``_`` takes no options.
|
||||
``_`` has no options.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
> _ File
|
||||
|
||||
@@ -6,152 +6,105 @@ abbr - manage fish abbreviations
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
abbr --add NAME [--position command | anywhere] [-r | --regex PATTERN]
|
||||
[--set-cursor[=MARKER]] ([-f | --function FUNCTION] | EXPANSION)
|
||||
abbr --erase NAME ...
|
||||
abbr --rename OLD_WORD NEW_WORD
|
||||
abbr --add [SCOPE] WORD EXPANSION
|
||||
abbr --erase WORD
|
||||
abbr --rename [SCOPE] OLD_WORD NEW_WORD
|
||||
abbr --show
|
||||
abbr --list
|
||||
abbr --query NAME ...
|
||||
abbr --query WORD...
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
``abbr`` manages abbreviations - user-defined words that are replaced with longer phrases when entered.
|
||||
``abbr`` manages abbreviations - user-defined words that are replaced with longer phrases after they are entered.
|
||||
|
||||
.. note::
|
||||
Only typed-in commands use abbreviations. Abbreviations are not expanded in scripts.
|
||||
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.
|
||||
|
||||
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.
|
||||
To avoid expanding something that looks like an abbreviation, the default :kbd:`Control`\ +\ :kbd:`Space` binding inserts a space without expanding.
|
||||
Options
|
||||
-------
|
||||
|
||||
An abbreviation may match a literal word, or it may match a pattern given by a regular expression. When an abbreviation matches a word, that word is replaced by new text, called its *expansion*. This expansion may be a fixed new phrase, or it can be dynamically created via a fish function. This expansion occurs after pressing space or enter.
|
||||
The following options are available:
|
||||
|
||||
Combining these features, it is possible to create custom syntaxes, where a regular expression recognizes matching tokens, and the expansion function interprets them. See the `Examples`_ section.
|
||||
- ``-a WORD EXPANSION`` or ``--add WORD EXPANSION`` Adds a new abbreviation, causing WORD to be expanded to EXPANSION.
|
||||
|
||||
.. versionchanged:: 3.6.0
|
||||
Previous versions of this allowed saving abbreviations in universal variables.
|
||||
That's no longer possible. Existing variables will still be imported and ``abbr --erase`` will also erase the variables.
|
||||
We recommend adding abbreviations to :ref:`config.fish <configuration>` by just adding the ``abbr --add`` command.
|
||||
When you run ``abbr``, you will see output like this
|
||||
- ``-r OLD_WORD NEW_WORD`` or ``--rename OLD_WORD NEW_WORD`` Renames an abbreviation, from OLD_WORD to NEW_WORD.
|
||||
|
||||
::
|
||||
- ``-s`` or ``--show`` Show all abbreviations in a manner suitable for export and import.
|
||||
|
||||
> abbr
|
||||
abbr -a -- foo bar # imported from a universal variable, see `help abbr`
|
||||
- ``-l`` or ``--list`` Lists all abbreviated words.
|
||||
|
||||
In that case you should take the part before the ``#`` comment and save it in :ref:`config.fish <configuration>`,
|
||||
then you can run ``abbr --erase`` to remove the universal variable::
|
||||
- ``-e WORD`` or ``--erase WORD`` Erase the abbreviation WORD.
|
||||
|
||||
> abbr >> ~/.config/fish/config.fish
|
||||
> abbr --erase (abbr --list)
|
||||
|
||||
- ``-q`` or ``--query`` Return 0 (true) if one of the WORDs is an abbreviation.
|
||||
|
||||
"add" subcommand
|
||||
--------------------
|
||||
In addition, when adding or renaming abbreviations:
|
||||
|
||||
.. synopsis::
|
||||
|
||||
abbr [-a | --add] NAME [--position command | anywhere] [-r | --regex PATTERN]
|
||||
[--set-cursor[=MARKER]] ([-f | --function FUNCTION] | EXPANSION)
|
||||
|
||||
``abbr --add`` creates a new abbreviation. With no other options, the string **NAME** is replaced by **EXPANSION**.
|
||||
|
||||
With **--position command**, the abbreviation will only expand when it is positioned as a command, not as an argument to another command. With **--position anywhere** the abbreviation may expand anywhere in the command line. The default is **command**.
|
||||
|
||||
With **--regex**, the abbreviation matches using the regular expression given by **PATTERN**, instead of the literal **NAME**. The pattern is interpreted using PCRE2 syntax and must match the entire token. If multiple abbreviations match the same token, the last abbreviation added is used.
|
||||
|
||||
With **--set-cursor=MARKER**, the cursor is moved to the first occurrence of **MARKER** in the expansion. The **MARKER** value is erased. The **MARKER** may be omitted (i.e. simply ``--set-cursor``), in which case it defaults to ``%``.
|
||||
|
||||
With **-f FUNCTION** or **--function FUNCTION**, **FUNCTION** is treated as the name of a fish function instead of a literal replacement. When the abbreviation matches, the function will be called with the matching token as an argument. If the function's exit status is 0 (success), the token will be replaced by the function's output; otherwise the token will be left unchanged. No **EXPANSION** may be given separately.
|
||||
- ``-g`` or ``--global`` to use a global variable.
|
||||
- ``-U`` or ``--universal`` to use a universal variable (default).
|
||||
|
||||
See the "Internals" section for more on them.
|
||||
|
||||
Examples
|
||||
########
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
abbr --add gco git checkout
|
||||
|
||||
Add a new abbreviation where ``gco`` will be replaced with ``git checkout``.
|
||||
|
||||
::
|
||||
|
||||
abbr -a --position anywhere -- -C --color
|
||||
|
||||
Add a new abbreviation where ``-C`` will be replaced with ``--color``. The ``--`` allows ``-C`` to be treated as the name of the abbreviation, instead of an option.
|
||||
|
||||
::
|
||||
|
||||
abbr -a L --position anywhere --set-cursor "% | less"
|
||||
|
||||
Add a new abbreviation where ``L`` will be replaced with ``| less``, placing the cursor before the pipe.
|
||||
|
||||
|
||||
::
|
||||
|
||||
function last_history_item
|
||||
echo $history[1]
|
||||
abbr -a -g gco git checkout
|
||||
|
||||
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).
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
abbr -a -U l less
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
abbr -r gco gch
|
||||
|
||||
Renames an existing abbreviation from ``gco`` to ``gch``.
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
abbr -e gco
|
||||
|
||||
Erase the ``gco`` abbreviation.
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
ssh another_host abbr -s | source
|
||||
|
||||
Import the abbreviations defined on another_host over SSH.
|
||||
|
||||
Internals
|
||||
---------
|
||||
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.
|
||||
|
||||
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
|
||||
abbr -a !! --position anywhere --function last_history_item
|
||||
|
||||
This first creates a function ``last_history_item`` which outputs the last entered command. It then adds an abbreviation which replaces ``!!`` with the result of calling this function. Taken together, this is similar to the ``!!`` history expansion feature of bash.
|
||||
|
||||
::
|
||||
|
||||
function vim_edit
|
||||
echo vim $argv
|
||||
end
|
||||
abbr -a vim_edit_texts --position command --regex ".+\.txt" --function vim_edit
|
||||
|
||||
This first creates a function ``vim_edit`` which prepends ``vim`` before its argument. It then adds an abbreviation which matches commands ending in ``.txt``, and replaces the command with the result of calling this function. This allows text files to be "executed" as a command to open them in vim, similar to the "suffix alias" feature in zsh.
|
||||
|
||||
::
|
||||
|
||||
abbr 4DIRS --set-cursor=! "$(string join \n -- 'for dir in */' 'cd $dir' '!' 'cd ..' 'end')"
|
||||
|
||||
This creates an abbreviation "4DIRS" which expands to a multi-line loop "template." The template enters each directory and then leaves it. The cursor is positioned ready to enter the command to run in each directory, at the location of the ``!``, which is itself erased.
|
||||
|
||||
Other subcommands
|
||||
--------------------
|
||||
|
||||
|
||||
::
|
||||
|
||||
abbr --rename OLD_NAME NEW_NAME
|
||||
|
||||
Renames an abbreviation, from *OLD_NAME* to *NEW_NAME*
|
||||
|
||||
::
|
||||
|
||||
abbr [-s | --show]
|
||||
|
||||
Show all abbreviations in a manner suitable for import and export
|
||||
|
||||
::
|
||||
|
||||
abbr [-l | --list]
|
||||
|
||||
Prints the names of all abbreviation
|
||||
|
||||
::
|
||||
|
||||
abbr [-e | --erase] NAME
|
||||
|
||||
Erases the abbreviation with the given name
|
||||
|
||||
::
|
||||
|
||||
abbr -q or --query [NAME...]
|
||||
|
||||
Return 0 (true) if one of the *NAME* is an abbreviation.
|
||||
|
||||
::
|
||||
|
||||
abbr -h or --help
|
||||
|
||||
Displays help for the `abbr` command.
|
||||
|
||||
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.
|
||||
|
||||
@@ -6,40 +6,38 @@ alias - create a function
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
alias
|
||||
alias [--save] NAME DEFINITION
|
||||
alias [--save] NAME=DEFINITION
|
||||
alias [OPTIONS] NAME DEFINITION
|
||||
alias [OPTIONS] NAME=DEFINITION
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
``alias`` is a simple wrapper for the ``function`` builtin, which creates a function wrapping a command. It has similar syntax to POSIX shell ``alias``. For other uses, it is recommended to define a :doc:`function <function>`.
|
||||
|
||||
If you want to ease your interactive use, to save typing, consider using an :doc:`abbreviation <abbr>` instead.
|
||||
``alias`` is a simple wrapper for the ``function`` builtin, which creates a function wrapping a command. It has similar syntax to POSIX shell ``alias``. For other uses, it is recommended to define a :ref:`function <cmd-function>`.
|
||||
|
||||
``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
|
||||
- ``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*.
|
||||
|
||||
The following options are available:
|
||||
|
||||
**-h** or **--help**
|
||||
Displays help about using this command.
|
||||
- ``-h`` or ``--help`` displays help about using this command.
|
||||
|
||||
**-s** or **--save**
|
||||
Saves the function created by the alias into your fish configuration directory using :doc:`funcsave <funcsave>`.
|
||||
- ``-s`` or ``--save`` Automatically save the function created by the alias into your fish configuration directory using :ref:`funcsave <cmd-funcsave>`.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
The following code will create ``rmi``, which runs ``rm`` with additional arguments on every invocation.
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
alias rmi="rm -i"
|
||||
@@ -49,14 +47,6 @@ The following code will create ``rmi``, which runs ``rm`` with additional argume
|
||||
rm -i $argv
|
||||
end
|
||||
|
||||
# This needs to have the spaces escaped or "Chrome.app..."
|
||||
# will be seen as an argument to "/Applications/Google":
|
||||
# This needs to have the spaces escaped or "Chrome.app..." will be seen as an argument to "/Applications/Google":
|
||||
alias chrome='/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome banana'
|
||||
|
||||
|
||||
See more
|
||||
--------
|
||||
|
||||
1. The :doc:`function <function>` command this builds on.
|
||||
2. :ref:`Functions <syntax-function>`.
|
||||
3. :ref:`Defining aliases <syntax-aliases>`.
|
||||
|
||||
@@ -6,21 +6,19 @@ and - conditionally execute a command
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
PREVIOUS; and COMMAND
|
||||
COMMAND1; and COMMAND2
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
``and`` is used to execute a command if the previous command was successful (returned a status of 0).
|
||||
|
||||
``and`` statements may be used as part of the condition in an :doc:`while <while>` or :doc:`if <if>` block.
|
||||
``and`` statements may be used as part of the condition in an :ref:`while <cmd-while>` or :ref:`if <cmd-if>` block.
|
||||
|
||||
``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
|
||||
-------
|
||||
|
||||
@@ -33,5 +31,4 @@ The following code runs the ``make`` command to build a program. If the build su
|
||||
See Also
|
||||
--------
|
||||
|
||||
- :doc:`or <or>` command
|
||||
- :doc:`not <not>` command
|
||||
- :ref:`or <cmd-or>` command
|
||||
|
||||
@@ -6,145 +6,127 @@ argparse - parse options passed to a fish script or function
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
argparse [OPTIONS] OPTION_SPEC ... -- [ARG ...]
|
||||
argparse [OPTIONS] OPTION_SPEC... -- [ARG...]
|
||||
|
||||
|
||||
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
|
||||
-------
|
||||
|
||||
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**
|
||||
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.
|
||||
- ``-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.
|
||||
|
||||
**-x** or **--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.
|
||||
- ``-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.
|
||||
|
||||
**-N** or **--min-args** *NUMBER*
|
||||
The minimum number of acceptable non-option arguments. The default is zero.
|
||||
- ``-N`` or ``--min-args`` is followed by an integer that defines the minimum number of acceptable non-option arguments. The default is zero.
|
||||
|
||||
**-X** or **--max-args** *NUMBER*
|
||||
The maximum number of acceptable non-option arguments. The default is infinity.
|
||||
- ``-X`` or ``--max-args`` is followed by an integer that defines the maximum number of acceptable non-option arguments. The default is infinity.
|
||||
|
||||
**-i** or **--ignore-unknown**
|
||||
Ignores unknown options, keeping them and their arguments in $argv instead.
|
||||
- ``-i`` or ``--ignore-unknown`` ignores unknown options, keeping them and their arguments in $argv instead.
|
||||
|
||||
**-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.
|
||||
- ``-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.
|
||||
|
||||
**-h** or **--help**
|
||||
Displays help about using this command.
|
||||
|
||||
.. _cmd-argparse-usage:
|
||||
- ``-h`` or ``--help`` displays help about using this command.
|
||||
|
||||
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
|
||||
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 option specifications or 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 foo
|
||||
|
||||
|
||||
::
|
||||
|
||||
set -l argv
|
||||
argparse 'h/help' 'n/name' -- $argv
|
||||
argparse --min-args=1 -- $argv
|
||||
|
||||
But this is not::
|
||||
|
||||
But this is not:
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
set -l 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
|
||||
---------------------
|
||||
|
||||
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.
|
||||
|
||||
See the :doc:`fish_opt <fish_opt>` command for a friendlier but more verbose way to create option specifications.
|
||||
- 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.
|
||||
|
||||
If a flag is not seen when parsing the arguments then the corresponding _flag_X var(s) will not be set.
|
||||
See the :ref:`fish_opt <cmd-fish_opt>` command for a friendlier but more verbose way to create option specifications.
|
||||
|
||||
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``.
|
||||
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.
|
||||
|
||||
Note: Optional arguments
|
||||
------------------------
|
||||
|
||||
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
|
||||
# or
|
||||
cmd -fvalue
|
||||
|
||||
but not if used like::
|
||||
but not::
|
||||
|
||||
cmd --flag value
|
||||
# "value" here will be used as a positional argument
|
||||
# and "--flag" won't have an argument.
|
||||
# "value" here will be used as a positional 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.
|
||||
|
||||
For example::
|
||||
|
||||
grep --color auto
|
||||
# Here "auto" will be used as the search string,
|
||||
# "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".
|
||||
# Here "auto" will be used as the search string, "color" will not have an argument and will fall back to the default
|
||||
|
||||
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.
|
||||
|
||||
.. _flag-value-validation:
|
||||
This isn't specific to argparse but common to all things using ``getopt(3)`` (if they have optional arguments at all).
|
||||
|
||||
Flag Value Validation
|
||||
---------------------
|
||||
@@ -163,59 +145,31 @@ The script should write any error messages to stdout, not stderr. It should retu
|
||||
|
||||
Fish ships with a ``_validate_int`` function that accepts a ``--min`` and ``--max`` flag. Let's say your command accepts a ``-m`` or ``--max`` flag and the minimum allowable value is zero and the maximum is 5. You would define the option like this: ``m/max=!_validate_int --min 0 --max 5``. The default if you just call ``_validate_int`` without those flags is to simply check that the value is a valid integer with no limits on the min or max value allowed.
|
||||
|
||||
Here are some examples of flag validations::
|
||||
|
||||
# validate that a path is a directory
|
||||
argparse 'p/path=!test -d "$_flag_value"' -- --path $__fish_config_dir
|
||||
# validate that a function does not exist
|
||||
argparse 'f/func=!not functions -q "$_flag_value"' -- -f alias
|
||||
# validate that a string matches a regex
|
||||
argparse 'c/color=!string match -rq \'^#?[0-9a-fA-F]{6}$\' "$_flag_value"' -- -c 'c0ffee'
|
||||
# validate with a validator function
|
||||
argparse 'n/num=!_validate_int --min 0 --max 99' -- --num 42
|
||||
|
||||
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 however either flag was seen, as many times as it was seen. So it could be set to ``-h``, ``-h`` and ``--help``, and ``count $_flag_h`` would yield "3".
|
||||
- ``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 as above. Also ``h-help`` (with an arbitrary short letter) for backwards compatibility.
|
||||
|
||||
- ``longonly=`` is a flag ``--longonly`` that requires an option, there is no short flag or even short flag variable.
|
||||
- ``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.
|
||||
|
||||
- ``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.
|
||||
|
||||
- ``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 as above.
|
||||
- ``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``.
|
||||
|
||||
- ``#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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -6,28 +6,30 @@ begin - start a new block of code
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
begin; [COMMANDS...;] end
|
||||
|
||||
begin; [COMMANDS ...]; end
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
``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``.
|
||||
|
||||
``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
|
||||
-------
|
||||
|
||||
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
|
||||
@@ -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.
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
begin
|
||||
@@ -53,3 +57,4 @@ In the following code, all output is redirected to the file out.html.
|
||||
end
|
||||
...
|
||||
end > out.html
|
||||
|
||||
|
||||
@@ -6,33 +6,27 @@ bg - send jobs to background
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
bg [PID ...]
|
||||
bg [PID...]
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
``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 :doc:`jobs <jobs>`.
|
||||
|
||||
When at least one of the arguments isn't a valid job specifier,
|
||||
When at least one of the arguments isn't a valid job specifier (i.e. PID),
|
||||
``bg`` will print an error without backgrounding anything.
|
||||
|
||||
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.
|
||||
When all arguments are valid job specifiers, bg will background all matching jobs that exist.
|
||||
|
||||
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.
|
||||
|
||||
``bg 123 banana`` or ``bg banana 123`` will complain that "banana" is not a valid job specifier.
|
||||
|
||||
``bg %1`` will background job 1.
|
||||
|
||||
@@ -2,17 +2,18 @@
|
||||
|
||||
bind - handle fish key bindings
|
||||
===============================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
bind [(-M | --mode) MODE] [(-m | --sets-mode) NEW_MODE] [--preset | --user] [-s | --silent] [-k | --key] SEQUENCE COMMAND ...
|
||||
bind [(-M | --mode) MODE] [-k | --key] [--preset] [--user] SEQUENCE
|
||||
bind (-K | --key-names) [-a | --all] [--preset] [--user]
|
||||
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 (-K | --key-names) [(-a | --all)] [--preset] [--user]
|
||||
bind (-f | --function-names)
|
||||
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
|
||||
-----------
|
||||
@@ -27,335 +28,197 @@ 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.
|
||||
|
||||
To find out what sequence a key combination sends, you can use :doc:`fish_key_reader <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.
|
||||
|
||||
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.
|
||||
|
||||
.. note::
|
||||
Special input functions cannot be combined with ordinary shell script commands. The commands must be entirely a sequence of special input functions (from ``bind -f``) or all shell script commands (i.e., valid fish script). To run special input functions from regular fish script, use ``commandline -f`` (see also :doc:`commandline <commandline>`). If a script produces output, it should finish by calling ``commandline -f repaint`` to tell fish that a repaint is in order.
|
||||
Note that special input functions cannot be combined with ordinary shell script commands. The commands must be entirely a sequence of special input functions (from ``bind -f``) or all shell script commands (i.e., valid fish 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.
|
||||
|
||||
To save custom key bindings, 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". Every key binding applies to a single mode; you can specify which one with ``-M MODE``. If the key binding should change the mode, you can specify the new mode with ``-m NEW_MODE``. The mode can be viewed and changed via the ``$fish_bind_mode`` variable. If you want to change the mode from inside a fish function, use ``set fish_bind_mode MODE``.
|
||||
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.
|
||||
|
||||
Options
|
||||
-------
|
||||
The following options are available:
|
||||
|
||||
**-k** or **--key**
|
||||
Specify a key name, such as 'left' or 'backspace' instead of a character sequence
|
||||
- ``-k`` or ``--key`` Specify a key name, such as 'left' or 'backspace' instead of a character sequence
|
||||
|
||||
**-K** or **--key-names**
|
||||
Display a list of available key names. Specifying **-a** or **--all** includes keys that don't have a known mapping
|
||||
- ``-K`` or ``--key-names`` Display a list of available key names. Specifying ``-a`` or ``--all`` includes keys that don't have a known mapping
|
||||
|
||||
**-f** or **--function-names**
|
||||
Display a list of available input functions
|
||||
- ``-f`` or ``--function-names`` Display a list of available input functions
|
||||
|
||||
**-L** or **--list-modes**
|
||||
Display a list of defined bind modes
|
||||
- ``-L`` or ``--list-modes`` Display a list of defined bind modes
|
||||
|
||||
**-M MODE** or **--mode** *MODE*
|
||||
Specify a bind mode that the bind is used in. Defaults to "default"
|
||||
- ``-M MODE`` or ``--mode MODE`` Specify a bind mode that the bind is used in. Defaults to "default"
|
||||
|
||||
**-m NEW_MODE** or **--sets-mode** *NEW_MODE*
|
||||
Change the current mode to *NEW_MODE* after this binding is executed
|
||||
- ``-m NEW_MODE`` or ``--sets-mode NEW_MODE`` Change the current mode to ``NEW_MODE`` after this binding is executed
|
||||
|
||||
**-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.
|
||||
- ``-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.
|
||||
|
||||
**-a** or **--all**
|
||||
See **--erase** and **--key-names**
|
||||
- ``-a`` or ``--all`` See ``--erase`` and ``--key-names``
|
||||
|
||||
**--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``).
|
||||
|
||||
**-s** or **--silent**
|
||||
Silences some of the error messages, including for unknown key names and unbound sequences.
|
||||
|
||||
**-h** or **--help**
|
||||
Displays help about using this command.
|
||||
- ``--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``).
|
||||
|
||||
Special input functions
|
||||
-----------------------
|
||||
The following special input functions are available:
|
||||
|
||||
``and``
|
||||
only execute the next function if the previous succeeded (note: only some functions report success)
|
||||
- ``and``, only execute the next function if the previous succeeded (note: only some functions report success)
|
||||
|
||||
``accept-autosuggestion``
|
||||
accept the current autosuggestion
|
||||
- ``accept-autosuggestion``, accept the current autosuggestion completely
|
||||
|
||||
``backward-char``
|
||||
move one character to the left.
|
||||
If the completion pager is active, select the previous completion instead.
|
||||
- ``backward-char``, moves one character to the left
|
||||
|
||||
``backward-bigword``
|
||||
move one whitespace-delimited word to the left
|
||||
- ``backward-bigword``, move one whitespace-delimited word to the left
|
||||
|
||||
``backward-delete-char``
|
||||
deletes one character of input to the left of the cursor
|
||||
- ``backward-delete-char``, deletes one character of input to the left of the cursor
|
||||
|
||||
``backward-kill-bigword``
|
||||
move the whitespace-delimited word to the left of the cursor to the killring
|
||||
- ``backward-kill-bigword``, move the whitespace-delimited word to the left of the cursor to the killring
|
||||
|
||||
``backward-kill-line``
|
||||
move everything from the beginning of the line to the cursor to the killring
|
||||
- ``backward-kill-line``, move everything from the beginning of the line to the cursor to the killring
|
||||
|
||||
``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.
|
||||
- ``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.
|
||||
|
||||
``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.
|
||||
- ``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.
|
||||
|
||||
``backward-word``
|
||||
move one word to the left
|
||||
- ``backward-word``, move one word to the left
|
||||
|
||||
``beginning-of-buffer``
|
||||
moves to the beginning of the buffer, i.e. the start of the first line
|
||||
- ``beginning-of-buffer``, moves to the beginning of the buffer, i.e. the start of the first line
|
||||
|
||||
``beginning-of-history``
|
||||
move to the beginning of the history
|
||||
- ``beginning-of-history``, move to the beginning of the history
|
||||
|
||||
``beginning-of-line``
|
||||
move to the beginning of the line
|
||||
- ``beginning-of-line``, move to the beginning of the line
|
||||
|
||||
``begin-selection``
|
||||
start selecting text
|
||||
- ``begin-selection``, start selecting text
|
||||
|
||||
``cancel``
|
||||
cancel the current commandline and replace it with a new empty one
|
||||
- ``cancel``, cancel the current commandline and replace it with a new empty one
|
||||
|
||||
``cancel-commandline``
|
||||
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``, make the current word begin with a capital letter
|
||||
|
||||
``capitalize-word``
|
||||
make the current word begin with a capital letter
|
||||
- ``complete``, guess the remainder of the current token
|
||||
|
||||
``clear-screen``
|
||||
clears the screen and redraws the prompt. if the terminal doesn't support clearing the screen it is the same as ``repaint``.
|
||||
- ``complete-and-search``, invoke the searchable pager on completion options (for convenience, this also moves backwards in the completion pager)
|
||||
|
||||
``complete``
|
||||
guess the remainder of the current token
|
||||
- ``delete-char``, delete one character to the right of the cursor
|
||||
|
||||
``complete-and-search``
|
||||
invoke the searchable pager on completion options (for convenience, this also moves backwards in the completion pager)
|
||||
- ``delete-or-exit``, deletes one character to the right of the cursor or exits the shell if the commandline is empty.
|
||||
|
||||
``delete-char``
|
||||
delete one character to the right of the cursor
|
||||
- ``down-line``, move down one line
|
||||
|
||||
``delete-or-exit``
|
||||
delete one character to the right of the cursor, or exit the shell if the commandline is empty
|
||||
- ``downcase-word``, make the current word lowercase
|
||||
|
||||
``down-line``
|
||||
move down one line
|
||||
- ``end-of-buffer``, moves to the end of the buffer, i.e. the end of the first line
|
||||
|
||||
``downcase-word``
|
||||
make the current word lowercase
|
||||
- ``end-of-history``, move to the end of the history
|
||||
|
||||
``end-of-buffer``
|
||||
moves to the end of the buffer, i.e. the end of the first line
|
||||
- ``end-of-line``, move to the end of the line
|
||||
|
||||
``end-of-history``
|
||||
move to the end of the history
|
||||
- ``end-selection``, end selecting text
|
||||
|
||||
``end-of-line``
|
||||
move to the end of the line
|
||||
- ``expand-abbr`` expands any abbreviation currently under the cursor
|
||||
|
||||
``end-selection``
|
||||
end selecting text
|
||||
- ``execute`` run the current commandline
|
||||
|
||||
``expand-abbr``
|
||||
expands any abbreviation currently under the cursor
|
||||
- ``force-repaint`` reexecute the prompt functions without coalescing
|
||||
|
||||
``execute``
|
||||
run the current commandline
|
||||
- ``forward-bigword``, move one whitespace-delimited word to the right
|
||||
|
||||
``exit``
|
||||
exit the shell
|
||||
- ``forward-char``, move one character to the right
|
||||
|
||||
``forward-bigword``
|
||||
move one whitespace-delimited word to the right
|
||||
- ``forward-word``, move one word to the right
|
||||
|
||||
``forward-char``
|
||||
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.
|
||||
- ``history-search-backward``, search the history for the previous match
|
||||
|
||||
``forward-single-char``
|
||||
move one character to the right; or if at the end of the commandline, accept a single char from the current autosuggestion.
|
||||
- ``history-search-forward``, search the history for the next match
|
||||
|
||||
``forward-word``
|
||||
move one word to the right; or if at the end of the commandline, accept one word
|
||||
from the current autosuggestion.
|
||||
- ``history-prefix-search-backward``, search the history for the previous prefix match
|
||||
|
||||
``history-pager``
|
||||
invoke the searchable pager on history (incremental search); or if the history pager is already active, search further backwards in time.
|
||||
- ``history-prefix-search-forward``, search the history for the next prefix match
|
||||
|
||||
``history-pager-delete``
|
||||
permanently delete the history item selected in the history pager
|
||||
- ``history-token-search-backward``, search the history for the previous matching argument
|
||||
|
||||
``history-search-backward``
|
||||
search the history for the previous match
|
||||
- ``history-token-search-forward``, search the history for the next matching argument
|
||||
|
||||
``history-search-forward``
|
||||
search the history for the next match
|
||||
- ``forward-jump`` and ``backward-jump``, read another character and jump to its next occurence after/before the cursor
|
||||
|
||||
``history-prefix-search-backward``
|
||||
search the history for the previous prefix match
|
||||
- ``forward-jump-till`` and ``backward-jump-till``, jump to right *before* the next occurence
|
||||
|
||||
``history-prefix-search-forward``
|
||||
search the history for the next prefix match
|
||||
- ``repeat-jump`` and ``repeat-jump-reverse``, redo the last jump in the same/opposite direction
|
||||
|
||||
``history-token-search-backward``
|
||||
search the history for the previous matching argument
|
||||
- ``kill-bigword``, move the next whitespace-delimited word to the killring
|
||||
|
||||
``history-token-search-forward``
|
||||
search the history for the next matching argument
|
||||
- ``kill-line``, move everything from the cursor to the end of the line to the killring
|
||||
|
||||
``forward-jump`` and ``backward-jump``
|
||||
read another character and jump to its next occurence after/before the cursor
|
||||
- ``kill-selection``, move the selected text to the killring
|
||||
|
||||
``forward-jump-till`` and ``backward-jump-till``
|
||||
jump to right *before* the next occurence
|
||||
- ``kill-whole-line``, move the line to the killring
|
||||
|
||||
``repeat-jump`` and ``repeat-jump-reverse``
|
||||
redo the last jump in the same/opposite direction
|
||||
- ``kill-word``, move the next word to the killring
|
||||
|
||||
``kill-bigword``
|
||||
move the next whitespace-delimited word to the killring
|
||||
- ``pager-toggle-search``, toggles the search field if the completions pager is visible.
|
||||
|
||||
``kill-line``
|
||||
move everything from the cursor to the end of the line to the killring
|
||||
- ``repaint`` reexecutes the prompt functions and redraws the prompt. Multiple successive repaints are coalesced.
|
||||
|
||||
``kill-selection``
|
||||
move the selected text to the killring
|
||||
- ``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.
|
||||
|
||||
``kill-whole-line``
|
||||
move the line (including the following newline) to the killring. If the line is the last line, its preceeding newline is also removed
|
||||
- ``self-insert``, inserts the matching sequence into the command line
|
||||
|
||||
``kill-inner-line``
|
||||
move the line (without the following newline) to the killring
|
||||
- ``self-insert-notfirst``, inserts the matching sequence into the command line, unless the cursor is at the beginning
|
||||
|
||||
``kill-word``
|
||||
move the next word to the killring
|
||||
- ``suppress-autosuggestion``, remove the current autosuggestion
|
||||
|
||||
``nextd-or-forward-word``
|
||||
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.
|
||||
- ``swap-selection-start-stop``, go to the other end of the highlighted text without changing the selection
|
||||
|
||||
``or``
|
||||
only execute the next function if the previous did not succeed (note: only some functions report failure)
|
||||
- ``transpose-chars``, transpose two characters to the left of the cursor
|
||||
|
||||
``pager-toggle-search``
|
||||
toggles the search field if the completions pager is visible; or if used after ``history-pager``, search forwards in time.
|
||||
- ``transpose-words``, transpose two words to the left of the cursor
|
||||
|
||||
``prevd-or-backward-word``
|
||||
if the commandline is empty, then move backward in the directory history, otherwise move one word to the left
|
||||
- ``up-line``, move up one line
|
||||
|
||||
``repaint``
|
||||
reexecutes the prompt functions and redraws the prompt (also ``force-repaint`` for backwards-compatibility)
|
||||
- ``undo`` and ``redo``, revert or redo the most recent edits on the command line
|
||||
|
||||
``repaint-mode``
|
||||
reexecutes the :doc:`fish_mode_prompt <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.
|
||||
- ``upcase-word``, make the current word uppercase
|
||||
|
||||
``self-insert``
|
||||
inserts the matching sequence into the command line
|
||||
- ``yank``, insert the latest entry of the killring into the buffer
|
||||
|
||||
``self-insert-notfirst``
|
||||
inserts the matching sequence into the command line, unless the cursor is at the beginning
|
||||
|
||||
``suppress-autosuggestion``
|
||||
remove the current autosuggestion. Returns true if there was a suggestion to remove.
|
||||
|
||||
``swap-selection-start-stop``
|
||||
go to the other end of the highlighted text without changing the selection
|
||||
|
||||
``transpose-chars``
|
||||
transpose two characters to the left of the cursor
|
||||
|
||||
``transpose-words``
|
||||
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.
|
||||
- ``yank-pop``, rotate to the previous entry of the killring
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Exit the shell when :kbd:`Control`\ +\ :kbd:`D` is pressed::
|
||||
::
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
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'
|
||||
|
||||
Causes :kbd:`Control`\ +\ :kbd:`G` to launch ``git diff`` and repaint the commandline afterwards.
|
||||
|
||||
.. _cmd-bind-termlimits:
|
||||
|
||||
Terminal Limitations
|
||||
@@ -365,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:
|
||||
|
||||
- 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
|
||||
|
||||
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:
|
||||
|
||||
@@ -380,6 +243,3 @@ The escape key can be used standalone, for example, to switch from insertion mod
|
||||
Holding alt and something else also typically sends escape, for example holding alt+a will send an escape character and then an "a".
|
||||
|
||||
fish waits for a period after receiving the escape character, to determine whether it is standalone or part of an escape sequence. While waiting, additional key presses make the escape key behave as a meta key. If no other key presses come in, it is handled as a standalone escape. The waiting period is set to 30 milliseconds (0.03 seconds). It can be configured by setting the ``fish_escape_delay_ms`` variable to a value between 10 and 5000 ms. This can be a universal variable that you set once from an interactive session.
|
||||
So the escape character has its own timeout configured with :envvar:`fish_escape_delay_ms`.
|
||||
|
||||
See also :ref:`Key sequences <interactive-key-sequences>`.
|
||||
|
||||
@@ -6,15 +6,15 @@ block - temporarily block delivery of events
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
block [OPTIONS...]
|
||||
|
||||
block [(--local | --global)]
|
||||
block --erase
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
``block`` prevents events triggered by ``fish`` or the :doc:`emit <emit>` command from being delivered and acted upon while the block is in place.
|
||||
``block`` prevents events triggered by ``fish`` or the :ref:`emit <cmd-emit>` command from being delivered and acted upon while the block is in place.
|
||||
|
||||
In functions, ``block`` can be useful while performing work that should not be interrupted by the shell.
|
||||
|
||||
@@ -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``
|
||||
|
||||
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**
|
||||
Release the block automatically at the end of the current innermost code block scope.
|
||||
- ``-g`` or ``--global`` Never automatically release the lock
|
||||
|
||||
**-g** or **--global**
|
||||
Never automatically release the lock.
|
||||
- ``-e`` or ``--erase`` Release global block
|
||||
|
||||
**-e** or **--erase**
|
||||
Release global block.
|
||||
|
||||
**-h** or **--help**
|
||||
Displays help about using this command.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
::
|
||||
|
||||
# Create a function that listens for events
|
||||
@@ -54,7 +48,8 @@ Example
|
||||
block -e
|
||||
# 'foo fired' will now be printed
|
||||
|
||||
|
||||
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.
|
||||
|
||||
@@ -6,21 +6,19 @@ break - stop the current inner loop
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
LOOP_CONSTRUCT; [COMMANDS...] break; [COMMANDS...] end
|
||||
|
||||
LOOP_CONSTRUCT
|
||||
[COMMANDS ...]
|
||||
break
|
||||
[COMMANDS ...]
|
||||
end
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
``break`` halts a currently running loop (*LOOP_CONSTRUCT*), such as a :doc:`for <for>` or :doc:`while <while>` loop. It is usually added inside of a conditional block such as an :doc:`if <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``.
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
The following code searches all .c files for "smurf", and halts at the first occurrence.
|
||||
@@ -37,4 +35,4 @@ The following code searches all .c files for "smurf", and halts at the first occ
|
||||
See Also
|
||||
--------
|
||||
|
||||
- the :doc:`continue <continue>` command, to skip the remainder of the current iteration of the current inner loop
|
||||
- the :ref:`continue <cmd-continue>` command, to skip the remainder of the current iteration of the current inner loop
|
||||
|
||||
@@ -6,10 +6,11 @@ breakpoint - launch debug mode
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
breakpoint
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
|
||||
@@ -6,31 +6,27 @@ builtin - run a builtin command
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
builtin [OPTIONS] BUILTINNAME
|
||||
builtin --query BUILTINNAME ...
|
||||
builtin --names
|
||||
builtin [OPTIONS...] BUILTINNAME
|
||||
builtin --query BUILTINNAMES...
|
||||
|
||||
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**
|
||||
Lists the names of all defined builtins.
|
||||
- ``-n`` or ``--names`` List 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. If any exist, it returns 0, 1 otherwise.
|
||||
|
||||
**-h** or **--help**
|
||||
Displays help about using this command.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
builtin jobs
|
||||
|
||||
@@ -6,12 +6,9 @@ case - conditionally execute a block of commands
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
switch VALUE
|
||||
[case [GLOB ...]
|
||||
[COMMAND ...]]
|
||||
end
|
||||
switch VALUE; [case [WILDCARD...]; [COMMANDS...]; ...] end
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
@@ -6,7 +6,7 @@ cd - change directory
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
cd [DIRECTORY]
|
||||
|
||||
@@ -14,22 +14,16 @@ Description
|
||||
-----------
|
||||
``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`.
|
||||
It is recommended to keep **.** as the first element of :envvar:`CDPATH`, or :envvar:`PWD` will be tried last.
|
||||
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.
|
||||
|
||||
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.
|
||||
See also :doc:`prevd <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.
|
||||
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.
|
||||
|
||||
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
|
||||
--------
|
||||
|
||||
|
||||
@@ -6,25 +6,20 @@ cdh - change to a recently visited directory
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
cdh [DIRECTORY]
|
||||
cdh [ directory ]
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
``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``.
|
||||
``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``.
|
||||
|
||||
Note that the ``cd`` command limits directory history to the 25 most recently visited directories.
|
||||
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.
|
||||
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.
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
- the :doc:`dirh <dirh>` command to print the directory history
|
||||
- the :doc:`prevd <prevd>` command to move backward
|
||||
- the :doc:`nextd <nextd>` command to move forward
|
||||
- the :ref:`dirh <cmd-dirh>` command to print the directory history
|
||||
- the :ref:`prevd <cmd-prevd>` command to move backward
|
||||
- the :ref:`nextd <cmd-nextd>` command to move forward
|
||||
|
||||
@@ -6,36 +6,32 @@ command - run a program
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
command [OPTIONS] [COMMANDNAME [ARG ...]]
|
||||
command [OPTIONS] COMMANDNAME [ARGS...]
|
||||
|
||||
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:
|
||||
|
||||
**-a** or **--all**
|
||||
Prints all *COMMAND* found in :envvar:`PATH`, in the order found.
|
||||
- ``-a`` or ``--all`` returns all the external COMMANDNAMEs that are found in ``$PATH`` in the order they are found.
|
||||
|
||||
**-q** or **--query**
|
||||
Silence output and print nothing, setting only exit status.
|
||||
Implies **--search**.
|
||||
For compatibility, this is also **--quiet** (deprecated).
|
||||
- ``-q`` or ``--quiet``, silences the output and prints nothing, setting only the exit status. Implies ``--search``.
|
||||
|
||||
**-v** (or **-s** or **--search**)
|
||||
Prints the external command that would be executed, or prints nothing if no file with the specified name could be found in :envvar:`PATH`.
|
||||
- ``-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``.
|
||||
|
||||
**-h** or **--help**
|
||||
Displays help about using this command.
|
||||
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.
|
||||
|
||||
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
|
||||
--------
|
||||
|
||||
| ``command ls`` executes the ``ls`` program, even if an ``ls`` function also 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 ls`` causes fish to execute the ``ls`` program, even if an ``ls`` function 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.
|
||||
|
||||
@@ -6,7 +6,7 @@ commandline - set or get the current command line buffer
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
commandline [OPTIONS] [CMD]
|
||||
|
||||
@@ -17,91 +17,50 @@ Description
|
||||
|
||||
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:
|
||||
|
||||
**-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.
|
||||
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.
|
||||
- ``-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.
|
||||
|
||||
**-B** or **--selection-start**
|
||||
Get current position of the selection start in the buffer.
|
||||
|
||||
**-E** or **--selection-end**
|
||||
Get current position of the selection end in the buffer.
|
||||
|
||||
**-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 :doc:`bind <bind>` for a list of input functions.
|
||||
|
||||
**-h** or **--help**
|
||||
Displays help about using this command.
|
||||
- ``-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.
|
||||
|
||||
The following options change the way ``commandline`` updates the command line buffer:
|
||||
|
||||
**-a** or **--append**
|
||||
Do not remove the current commandline, append the specified string at the end of it.
|
||||
- ``-a`` or ``--append`` do not remove the current commandline, append the specified string at the end of it
|
||||
|
||||
**-i** or **--insert**
|
||||
Do not remove the current commandline, insert the specified string at the current cursor position
|
||||
- ``-i`` or ``--insert`` do not remove the current commandline, insert the specified string at the current cursor position
|
||||
|
||||
**-r** or **--replace**
|
||||
Remove the current commandline and replace it with the specified string (default)
|
||||
- ``-r`` or ``--replace`` 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:
|
||||
|
||||
**-b** or **--current-buffer**
|
||||
Select the entire commandline, not including any displayed autosuggestion (default).
|
||||
- ``-b`` or ``--current-buffer`` select the entire buffer, including any displayed autosuggestion (default)
|
||||
|
||||
**-j** or **--current-job**
|
||||
Select the current job - a **job** here is one pipeline.
|
||||
Stops at logical operators or terminators (**;**, **&**, and newlines).
|
||||
- ``-j`` or ``--current-job`` select the current job - a `job` here is one pipeline. It stops at logical operators or terminators (`;`, `&` or newlines).
|
||||
|
||||
**-p** or **--current-process**
|
||||
Select the current process - a **process** here is one command.
|
||||
Stops at logical operators, terminators, and pipes.
|
||||
- ``-p`` or ``--current-process`` select the current process - a `process` here is one simple command. It stops at logical operators, terminators or pipes.
|
||||
|
||||
**-s** or **--current-selection**
|
||||
Selects the current selection
|
||||
- ``-s`` or ``--current-selection`` selects the current selection
|
||||
|
||||
**-t** or **--current-token**
|
||||
Selects the current token
|
||||
- ``-t`` or ``--current-token`` select the current token
|
||||
|
||||
The following options change the way ``commandline`` prints the current commandline buffer:
|
||||
|
||||
**-c** or **--cut-at-cursor**
|
||||
Only print selection up until the current cursor position.
|
||||
If combined with ``--tokenize``, this will print up until the last completed token - excluding the token the cursor is in.
|
||||
This is typically what you would want for instance in completions.
|
||||
To get both, use both ``commandline --cut-at-cursor --tokenize; commandline --cut-at-cursor --current-token``,
|
||||
or ``commandline -co; commandline -ct`` for short.
|
||||
- ``-c`` or ``--cut-at-cursor`` only print selection up until the current cursor position
|
||||
|
||||
**-o** or **--tokenize**
|
||||
Tokenize the selection and print one string-type token per line.
|
||||
- ``-o`` or ``--tokenize`` 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.
|
||||
|
||||
The following options output metadata about the commandline state:
|
||||
|
||||
**-L** or **--line**
|
||||
Print the line that the cursor is on, with the topmost line starting at 1.
|
||||
- ``-L`` or ``--line`` print the line that the cursor is on, with the topmost line starting at 1
|
||||
|
||||
**-S** or **--search-mode**
|
||||
Evaluates to true if the commandline is performing a history search.
|
||||
- ``-S`` or ``--search-mode`` evaluates to true if the commandline is performing a history search
|
||||
|
||||
**-P** or **--paging-mode**
|
||||
Evaluates to true if the commandline is showing pager contents, such as tab completions.
|
||||
- ``-P`` or ``--paging-mode`` 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
|
||||
-------
|
||||
@@ -118,29 +77,15 @@ If the commandline contains
|
||||
|
||||
(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.
|
||||
|
||||
The most common use for something like completions is
|
||||
|
||||
::
|
||||
|
||||
set -l tokens (commandline -opc)
|
||||
|
||||
which gives the current *process* (what is being completed), tokenized into separate entries, up to but excluding the currently being completed token
|
||||
|
||||
If you are then also interested in the in-progress token, add
|
||||
|
||||
::
|
||||
set -l current (commandline -ct)
|
||||
|
||||
Note that this makes it easy to render fish's infix matching moot - if possible it's best if the completions just print all possibilities and leave the matching to the current token up to fish's logic.
|
||||
`$flounder` is the current token.
|
||||
|
||||
More examples:
|
||||
|
||||
|
||||
::
|
||||
|
||||
>_ commandline -t
|
||||
|
||||
@@ -1,114 +1,119 @@
|
||||
.. _cmd-complete:
|
||||
|
||||
complete - edit command-specific tab-completions
|
||||
complete - edit command specific tab-completions
|
||||
================================================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
complete ((-c | --command) | (-p | --path)) COMMAND [OPTIONS]
|
||||
complete (-C | --do-complete) [--escape] STRING
|
||||
complete ( -c | --command | -p | --path ) COMMAND
|
||||
[( -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
|
||||
-----------
|
||||
|
||||
``complete`` defines, removes or lists completions for a command.
|
||||
|
||||
For an introduction to writing your own completions, see :ref:`Writing your own completions <completion-own>` in
|
||||
For an introduction to specifying completions, see :ref:`Writing your own completions <completion-own>` in
|
||||
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*
|
||||
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.
|
||||
- ``SHORT_OPTION`` is a one character option for the command.
|
||||
|
||||
**-p** or **--path** *COMMAND*
|
||||
Specifies that *COMMAND* is the absolute path of the command (optionally containing wildcards).
|
||||
- ``LONG_OPTION`` is a multi character option for the command.
|
||||
|
||||
**-e** or **--erase**
|
||||
Deletes the specified completion.
|
||||
- ``OPTION_ARGUMENTS`` is parameter containing a space-separated list of possible option-arguments, which may contain command substitutions.
|
||||
|
||||
**-s** or **--short-option** *SHORT_OPTION*
|
||||
Adds a short option to the completions list.
|
||||
- ``DESCRIPTION`` is a description of what the option and/or option arguments do.
|
||||
|
||||
**-l** or **--long-option** *LONG_OPTION*
|
||||
Adds a GNU-style long option to the completions list.
|
||||
- ``-c COMMAND`` or ``--command COMMAND`` specifies that ``COMMAND`` is the name of the command.
|
||||
|
||||
**-o** or **--old-option** *OPTION*
|
||||
Adds an old-style short or long option (see below for details).
|
||||
- ``-p COMMAND`` or ``--path COMMAND`` specifies that ``COMMAND`` is the absolute path of the program (optionally containing wildcards).
|
||||
|
||||
**-a** or **--arguments** *ARGUMENTS*
|
||||
Adds the specified option arguments to the completions list.
|
||||
- ``-e`` or ``--erase`` deletes the specified completion.
|
||||
|
||||
**-k** or **--keep-order**
|
||||
Keeps the order of *ARGUMENTS* instead of sorting alphabetically. Multiple ``complete`` calls with **-k** result in arguments of the later ones displayed first.
|
||||
- ``-s SHORT_OPTION`` or ``--short-option=SHORT_OPTION`` adds a short option to the completions list.
|
||||
|
||||
**-f** or **--no-files**
|
||||
This completion may not be followed by a filename.
|
||||
- ``-l LONG_OPTION`` or ``--long-option=LONG_OPTION`` adds a GNU style long option to the completions list.
|
||||
|
||||
**-F** or **--force-files**
|
||||
This completion may be followed by a filename, even if another applicable ``complete`` specified **--no-files**.
|
||||
- ``-o LONG_OPTION`` or ``--old-option=LONG_OPTION`` adds an old style long option to the completions list (See below for details).
|
||||
|
||||
**-r** or **--require-parameter**
|
||||
This completion must have an option argument, i.e. may not be followed by another option.
|
||||
- ``-a OPTION_ARGUMENTS`` or ``--arguments=OPTION_ARGUMENTS`` adds the specified option arguments to the completions list.
|
||||
|
||||
**-x** or **--exclusive**
|
||||
Short for **-r** and **-f**.
|
||||
- ``-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.
|
||||
|
||||
**-w** or **--wraps** *WRAPPED_COMMAND*
|
||||
Causes the specified command to inherit completions from *WRAPPED_COMMAND* (see below for details).
|
||||
- ``-f`` or ``--no-files`` says that the options specified by this completion may not be followed by a filename.
|
||||
|
||||
**-n** or **--condition** *CONDITION*
|
||||
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. If multiple conditions are specified, fish will try them in the order they are specified until one fails or all succeeded.
|
||||
- ``-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``.
|
||||
|
||||
**-C** or **--do-complete** *STRING*
|
||||
Makes ``complete`` try to find all possible completions for the specified string. If there is no *STRING*, the current commandline is used instead.
|
||||
- ``-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.
|
||||
|
||||
**--escape**
|
||||
When used with ``-C``, escape special characters in completions.
|
||||
- ``-x`` or ``--exclusive`` implies both ``-r`` and ``-f``.
|
||||
|
||||
**-h** or **--help**
|
||||
Displays help about using this command.
|
||||
- ``-w WRAPPED_COMMAND`` or ``--wraps=WRAPPED_COMMAND`` causes the specified command to inherit completions from the wrapped command (See below for details).
|
||||
|
||||
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 options, long like ``-Wall`` or ``-name`` or even short like ``-a``. Old-style options can be more than one character long, are preceded by a single hyphen and may not be grouped together. Option arguments are specified by default following a space (``-foo null``) or after ``=`` (``-foo=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.
|
||||
|
||||
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
|
||||
|
||||
|
||||
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:
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
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:
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
complete -c rpm -n "__fish_contains_opt -s e erase" -l nodeps -d "Don't check dependencies"
|
||||
@@ -142,12 +151,5 @@ To implement an alias, use the ``-w`` or ``--wraps`` option:
|
||||
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
|
||||
|
||||
Shows all completions for ``git``.
|
||||
|
||||
Any command ``foo`` that doesn't support grouping multiple short options in one string (not supporting ``-xf`` as short for ``-x -f``) or a short option and its value in one string (not supporting ``-d9`` instead of ``-d 9``) should be specified as a single-character old-style option instead of as a short-style option; for example, ``complete -c foo -o s; complete -c foo -o v`` would never suggest ``foo -ov`` but rather ``foo -o -v``.
|
||||
|
||||
@@ -6,32 +6,27 @@ contains - test if a word is present in a list
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
contains [OPTIONS] KEY [VALUES ...]
|
||||
contains [OPTIONS] KEY [VALUES...]
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
``contains`` tests whether the set *VALUES* contains the string *KEY*.
|
||||
If so, ``contains`` exits with code 0; if not, it exits with code 1.
|
||||
``contains`` tests whether the set ``VALUES`` contains the string ``KEY``. If so, ``contains`` exits with status 0; if not, it exits with status 1.
|
||||
|
||||
The following options are available:
|
||||
|
||||
**-i** or **--index**
|
||||
Print the index (number of the element in the set) of the first matching element.
|
||||
- ``-i`` or ``--index`` print the word index
|
||||
|
||||
**-h** or **--help**
|
||||
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.
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
The **--** here stops ``contains`` from treating **-q** to an option to itself.
|
||||
Instead it treats it as a normal string to check.
|
||||
The ``--`` here stops ``contains`` from treating ``-q`` to an option to itself. Instead it treats it as a normal string to check.
|
||||
|
||||
@@ -6,14 +6,14 @@ continue - skip the remainder of the current iteration of the current inner loop
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
LOOP_CONSTRUCT; [COMMANDS ...;] continue; [COMMANDS ...;] end
|
||||
LOOP_CONSTRUCT; [COMMANDS...;] continue; [COMMANDS...;] end
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
``continue`` skips the remainder of the current iteration of the current inner loop, such as a :doc:`for <for>` loop or a :doc:`while <while>` loop. It is usually added inside of a conditional block such as an :doc:`if <if>` statement or a :doc:`switch <switch>` statement.
|
||||
``continue`` skips the remainder of the current iteration of the current inner loop, such as a :ref:`for <cmd-for>` loop or a :ref:`while <cmd-while>` loop. It is usually added inside of a conditional block such as an :ref:`if <cmd-if>` statement or a :ref:`switch <cmd-switch>` statement.
|
||||
|
||||
Example
|
||||
-------
|
||||
@@ -35,4 +35,4 @@ The following code removes all tmp files that do not contain the word smurf.
|
||||
See Also
|
||||
--------
|
||||
|
||||
- the :doc:`break <break>` command, to stop the current inner loop
|
||||
- the :ref:`break <cmd-break>` command, to stop the current inner loop
|
||||
|
||||
@@ -6,11 +6,11 @@ count - count the number of elements of a list
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
count STRING1 STRING2 ...
|
||||
count $VARIABLE
|
||||
COMMAND | count
|
||||
count [...] < FILE
|
||||
count < FILE
|
||||
|
||||
Description
|
||||
-----------
|
||||
@@ -34,8 +34,7 @@ Example
|
||||
# Returns the number of directories in the users PATH variable.
|
||||
|
||||
count *.txt
|
||||
# Returns the number of files in the current working directory
|
||||
# ending with the suffix '.txt'.
|
||||
# Returns the number of files in the current working directory ending with the suffix '.txt'.
|
||||
|
||||
git ls-files --others --exclude-standard | count
|
||||
# Returns the number of untracked files in a git repository
|
||||
|
||||
@@ -6,7 +6,7 @@ dirh - print directory history
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
dirh
|
||||
|
||||
@@ -17,11 +17,11 @@ Description
|
||||
|
||||
``dirh`` does not accept any parameters.
|
||||
|
||||
Note that the :doc:`cd <cd>` command limits directory history to the 25 most recently visited directories. The history is stored in the ``$dirprev`` and ``$dirnext`` variables.
|
||||
Note that the :ref:`cd <cmd-cd>` command limits directory history to the 25 most recently visited directories. The history is stored in the ``$dirprev`` and ``$dirnext`` variables.
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
- the :doc:`cdh <cdh>` command to display a prompt to quickly navigate the history
|
||||
- the :doc:`prevd <prevd>` command to move backward
|
||||
- the :doc:`nextd <nextd>` command to move forward
|
||||
- the :ref:`cdh <cmd-cdh>` command to display a prompt to quickly navigate the history
|
||||
- the :ref:`prevd <cmd-prevd>` command to move backward
|
||||
- the :ref:`nextd <cmd-nextd>` command to move forward
|
||||
|
||||
@@ -6,26 +6,21 @@ dirs - print directory stack
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
dirs [-c]
|
||||
dirs
|
||||
dirs -c
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
``dirs`` prints the current :ref:`directory stack <directory-stack>`, as created by :doc:`pushd <pushd>` and modified by :doc:`popd <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**:
|
||||
Clear the directory stack instead of printing it.
|
||||
|
||||
**-h** or **--help**
|
||||
Displays help about using this command.
|
||||
|
||||
``dirs`` does not accept any arguments.
|
||||
``dirs`` does not accept any parameters.
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
- the :doc:`cdh <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.
|
||||
|
||||
@@ -6,9 +6,9 @@ disown - remove a process from the list of jobs
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
disown [PID ...]
|
||||
disown [ PID ... ]
|
||||
|
||||
Description
|
||||
-----------
|
||||
@@ -17,17 +17,15 @@ Description
|
||||
|
||||
Jobs in the list of jobs are sent a hang-up signal when fish terminates, which usually causes the job to terminate; ``disown`` allows these processes to continue regardless.
|
||||
|
||||
If no process is specified, the most recently-used job is removed (like :doc:`bg <bg>` and :doc:`fg <fg>`). If one or more PIDs are specified, jobs with the specified process IDs are removed from the job list. Invalid jobs are ignored and a warning is printed.
|
||||
If no process is specified, the most recently-used job is removed (like :ref:`bg <cmd-bg>` and :ref:`fg <cmd-fg>`). If one or more PIDs are specified, jobs with the specified process IDs are removed from the job list. Invalid jobs are ignored and a warning is printed.
|
||||
|
||||
If a job is stopped, it is sent a signal to continue running, and a warning is printed. It is not possible to use the :doc:`bg <bg>` builtin to continue a job once it has been disowned.
|
||||
If a job is stopped, it is sent a signal to continue running, and a warning is printed. It is not possible to use the :ref:`bg <cmd-bg>` builtin to continue a job once it has been disowned.
|
||||
|
||||
``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
|
||||
-------
|
||||
|
||||
``firefox &; disown`` will start the Firefox web browser in the background and remove it from the job list, meaning it will not be closed when the fish process is closed.
|
||||
|
||||
``disown (jobs -p)`` removes all :doc:`jobs <jobs>` from the job list without terminating them.
|
||||
``disown (jobs -p)`` removes all :ref:`jobs <cmd-jobs>` from the job list without terminating them.
|
||||
|
||||
@@ -6,30 +6,24 @@ echo - display a line of text
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
echo [OPTIONS] [STRING]
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
``echo`` displays *STRING* of text.
|
||||
``echo`` displays a string of text.
|
||||
|
||||
The following options are available:
|
||||
|
||||
**-n**
|
||||
Do not output a newline.
|
||||
- ``-n``, Do not output a newline
|
||||
|
||||
**-s**
|
||||
Do not separate arguments with spaces.
|
||||
- ``-s``, Do not separate arguments with spaces
|
||||
|
||||
**-E**
|
||||
Disable interpretation of backslash escapes (default).
|
||||
- ``-E``, Disable interpretation of backslash escapes (default)
|
||||
|
||||
**-e**
|
||||
Enable interpretation of backslash escapes.
|
||||
|
||||
Unlike other shells, this echo accepts ``--`` to signal the end of the options.
|
||||
- ``-e``, Enable interpretation of backslash escapes
|
||||
|
||||
Escape Sequences
|
||||
----------------
|
||||
@@ -65,17 +59,17 @@ Example
|
||||
|
||||
::
|
||||
|
||||
> echo 'Hello World'
|
||||
Hello World
|
||||
echo 'Hello World'
|
||||
|
||||
> echo -e 'Top\nBottom'
|
||||
Top
|
||||
Bottom
|
||||
Print hello world to stdout
|
||||
|
||||
> echo -- -n
|
||||
-n
|
||||
::
|
||||
|
||||
echo -e 'Top\\nBottom'
|
||||
|
||||
Print Top and Bottom on separate lines, using an escape sequence
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
- the :doc:`printf <printf>` command, for more control over output formatting
|
||||
- the :ref:`printf <cmd-printf>` command, for more control over output formatting
|
||||
|
||||
@@ -6,22 +6,22 @@ else - execute command if a condition is not met
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
if CONDITION; COMMANDS_TRUE ...; [else; COMMANDS_FALSE ...;] end
|
||||
if CONDITION; COMMANDS_TRUE...; [else; COMMANDS_FALSE...;] end
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
:doc:`if <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.
|
||||
: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.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
|
||||
@@ -6,16 +6,15 @@ emit - emit a generic event
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
::
|
||||
|
||||
emit EVENT_NAME [ARGUMENTS ...]
|
||||
emit EVENT_NAME [ARGUMENTS...]
|
||||
|
||||
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.
|
||||
|
||||
The **--help** or **-h** option displays help about using this command.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user