Merge branch 'master' into coverity_scan_master

This commit is contained in:
ridiculousfish
2020-06-08 00:27:50 -07:00
955 changed files with 32391 additions and 137717 deletions

17
.clang-tidy Normal file
View File

@@ -0,0 +1,17 @@
---
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
FormatStyle: File
CheckOptions:
- key: cert-dcl16-c.NewSuffixes
value: 'L;LL;LU;LLU'
- key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
value: '0'
- key: modernize-loop-convert.MinConfidence
value: 'risky'
- key: modernize-use-auto.RemoveStars
value: '1'
...

4
.gitattributes vendored
View File

@@ -24,8 +24,8 @@
/.travis.yml export-ignore
# for linguist; let github identify our project as C++ instead of C due to pcre2
/pcre2-10.32/* linguist-vendored
/pcre2/* linguist-vendored
angular.js linguist-vendored
/doc_src/* linguist-documentation
*.fish linguist-language=fish
tests/*.in linguist-language=fish
/tests/*.in linguist-language=fish

View File

@@ -8,4 +8,4 @@ Fixes issue #
<!-- Just check off what what we know been done so far. We can help you with this stuff. -->
- [ ] Changes to fish usage are reflected in user documentation/manpages.
- [ ] Tests have been added for regressions fixed
- [ ] User-visible changes noted in CHANGELOG.md
- [ ] User-visible changes noted in CHANGELOG.rst

16
.github/workflows/lockthreads.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: 'Lock threads'
on:
schedule:
- cron: '0 * * * *'
jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2
with:
github-token: ${{ github.token }}
issue-lock-inactive-days: '90'
pr-lock-inactive-days: '90'
issue-exclude-labels: 'question'

48
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,48 @@
name: C/C++ CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
ubuntu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install deps
run: |
sudo apt install expect gettext libncurses5-dev libpcre2-dev
- name: cmake
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: |
# brew install pcre2
# - name: cmake
# run: |
# mkdir build && cd build
# cmake ..
# - name: make
# run: |
# make
# - name: make test
# run: |
# make test

1
.gitignore vendored
View File

@@ -67,6 +67,7 @@ messages.pot
/toc.txt
/version
fish-build-version-witness.txt
__pycache__
# File names that can appear below the project root that represent artifacts
# from building and testing.

View File

@@ -13,7 +13,10 @@ matrix:
- gettext
- libncurses5-dev
- libpcre2-dev
- python
- 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"
@@ -26,7 +29,10 @@ matrix:
- gettext
- lib32ncurses5-dev
- g++-multilib
- python
- python3
- python3-pip
before_install:
- sudo pip3 install pexpect
env:
- CXXFLAGS="-m32 -Werror=address -Werror=return-type" CFLAGS="-m32"
- os: linux
@@ -35,6 +41,8 @@ matrix:
- 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:
@@ -43,10 +51,14 @@ matrix:
- 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:
@@ -54,7 +66,8 @@ matrix:
- gettext
- libncurses5-dev
- libpcre2-dev
- python
- python3
- python3-pip
coverity_scan:
project:
name: "fish-shell/fish-shell"
@@ -66,8 +79,7 @@ matrix:
branch_pattern: coverity_scan_master
- os: osx
before_install:
- brew update
- brew install pcre2 # use system PCRE2
- sudo pip3 install pexpect
fast_finish: true
script:

File diff suppressed because it is too large Load Diff

2695
CHANGELOG.rst Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,31 +1,34 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
cmake_minimum_required(VERSION 3.2)
IF(POLICY CMP0066)
CMAKE_POLICY(SET CMP0066 OLD)
ENDIF()
IF(POLICY CMP0067)
CMAKE_POLICY(SET CMP0067 NEW)
ENDIF()
if(POLICY CMP0066)
cmake_policy(SET CMP0066 OLD)
endif()
if(POLICY CMP0067)
cmake_policy(SET CMP0067 NEW)
endif()
PROJECT(fish)
include(cmake/Mac.cmake)
project(fish)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# We are C++11.
SET(CMAKE_CXX_STANDARD 11)
SET(DEFAULT_BUILD_TYPE "RelWithDebInfo")
set(CMAKE_CXX_STANDARD 11)
set(DEFAULT_BUILD_TYPE "RelWithDebInfo")
# Use the default flags (#6296) but remove -DNDEBUG so that asserts remain enabled.
STRING(REPLACE "-DNDEBUG" ""
string(REPLACE "-DNDEBUG" ""
CMAKE_CXX_FLAGS_RELWITHDEBINFO
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
STRING(REPLACE "-DNDEBUG" ""
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()
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()
# Force colored warnings in Ninja's output, if the compiler has -fdiagnostics-color support.
# Rationale in https://github.com/ninja-build/ninja/issues/814
@@ -51,11 +54,11 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra \
")
# Disable exception handling.
ADD_COMPILE_OPTIONS(-fno-exceptions)
add_compile_options(-fno-exceptions)
# 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
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")
@@ -63,37 +66,37 @@ if (UNIX AND NOT APPLE)
endif()
# Hide the CMake Rules directories in Xcode projects.
SOURCE_GROUP("CMake Rules" REGULAR_EXPRESSION "^$")
source_group("CMake Rules" REGULAR_EXPRESSION "^$")
# Put source and header files at top level under targets.
SOURCE_GROUP("Source Files" REGULAR_EXPRESSION "^$")
SOURCE_GROUP("Header Files" REGULAR_EXPRESSION "^$")
SOURCE_GROUP("Builtins" REGULAR_EXPRESSION "builtin_.*")
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)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Work around issue where archive-built libs go in the wrong place.
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
IF(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
SET(FISH_IN_TREE_BUILD TRUE)
ELSE()
SET(FISH_IN_TREE_BUILD FALSE)
ENDIF()
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
set(FISH_IN_TREE_BUILD TRUE)
else()
set(FISH_IN_TREE_BUILD FALSE)
endif()
# NetBSD does weird things with finding libraries,
# making the tests fail by failing to find pcre.
#
# Keep the rpath used to build.
IF(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
ENDIF()
if(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
endif()
# All objects that the system needs to build fish, except fish.cpp
SET(FISH_SRCS
set(FISH_SRCS
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
@@ -118,22 +121,22 @@ SET(FISH_SRCS
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/operation_context.cpp src/fd_monitor.cpp src/termsize.cpp
)
# Header files are just globbed.
FILE(GLOB FISH_HEADERS src/*.h)
file(GLOB FISH_HEADERS src/*.h)
# Set up config.h
INCLUDE(cmake/ConfigureChecks.cmake)
INCLUDE(cmake/gettext.cmake)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config_cmake.h.in
include(cmake/ConfigureChecks.cmake)
include(cmake/gettext.cmake)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config_cmake.h.in
${CMAKE_CURRENT_BINARY_DIR}/config.h)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Set up standard directories.
INCLUDE(GNUInstallDirs)
ADD_DEFINITIONS(-D_UNICODE=1
include(GNUInstallDirs)
add_definitions(-D_UNICODE=1
-DLOCALEDIR="${CMAKE_INSTALL_FULL_LOCALEDIR}"
-DPREFIX=L"${CMAKE_INSTALL_PREFIX}"
-DDATADIR=L"${CMAKE_INSTALL_FULL_DATADIR}"
@@ -143,84 +146,85 @@ ADD_DEFINITIONS(-D_UNICODE=1
# Set up the machinery around FISH-BUILD-VERSION-FILE
# This defines the FBVF variable.
INCLUDE(Version)
include(Version)
# Let fish pick up when we're running out of the build directory without installing
GET_FILENAME_COMPONENT(REAL_CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}" REALPATH)
GET_FILENAME_COMPONENT(REAL_CMAKE_SOURCE_DIR "${CMAKE_SOURCE_DIR}" REALPATH)
ADD_DEFINITIONS(-DCMAKE_BINARY_DIR="${REAL_CMAKE_BINARY_DIR}")
ADD_DEFINITIONS(-DCMAKE_SOURCE_DIR="${REAL_CMAKE_SOURCE_DIR}")
get_filename_component(REAL_CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}" REALPATH)
get_filename_component(REAL_CMAKE_SOURCE_DIR "${CMAKE_SOURCE_DIR}" REALPATH)
add_definitions(-DCMAKE_BINARY_DIR="${REAL_CMAKE_BINARY_DIR}")
add_definitions(-DCMAKE_SOURCE_DIR="${REAL_CMAKE_SOURCE_DIR}")
# Teach fish_version.o to rebuild when FBVF changes.
# The standard C++ include detection machinery misses this.
SET_SOURCE_FILES_PROPERTIES(src/fish_version.cpp
set_source_files_properties(src/fish_version.cpp
PROPERTIES OBJECT_DEPENDS
${CMAKE_CURRENT_BINARY_DIR}/${FBVF})
# Enable thread-safe errno on Solaris (#5611)
ADD_DEFINITIONS(-D_REENTRANT)
add_definitions(-D_REENTRANT)
# Set up PCRE2
INCLUDE(cmake/PCRE2.cmake)
include(cmake/PCRE2.cmake)
# Define a function to link dependencies.
FUNCTION(FISH_LINK_DEPS target)
TARGET_LINK_LIBRARIES(${target} fishlib)
ENDFUNCTION(FISH_LINK_DEPS)
function(FISH_LINK_DEPS_AND_SIGN target)
target_link_libraries(${target} fishlib)
codesign_on_mac(${target})
endfunction(FISH_LINK_DEPS_AND_SIGN)
# Define libfish.a.
ADD_LIBRARY(fishlib STATIC ${FISH_SRCS})
TARGET_SOURCES(fishlib PRIVATE ${FISH_HEADERS})
TARGET_LINK_LIBRARIES(fishlib
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})
# Define fish.
ADD_EXECUTABLE(fish src/fish.cpp)
FISH_LINK_DEPS(fish)
add_executable(fish src/fish.cpp)
fish_link_deps_and_sign(fish)
# Define fish_indent.
ADD_EXECUTABLE(fish_indent
add_executable(fish_indent
src/fish_indent.cpp src/print_help.cpp)
FISH_LINK_DEPS(fish_indent)
fish_link_deps_and_sign(fish_indent)
# Define fish_key_reader.
ADD_EXECUTABLE(fish_key_reader
add_executable(fish_key_reader
src/fish_key_reader.cpp src/print_help.cpp)
FISH_LINK_DEPS(fish_key_reader)
fish_link_deps_and_sign(fish_key_reader)
# Set up the docs.
INCLUDE(cmake/Docs.cmake)
include(cmake/Docs.cmake)
# A helper for running tests.
ADD_EXECUTABLE(fish_test_helper src/fish_test_helper.cpp)
add_executable(fish_test_helper src/fish_test_helper.cpp)
# Set up tests.
INCLUDE(cmake/Tests.cmake)
include(cmake/Tests.cmake)
# Benchmarking support.
INCLUDE(cmake/Benchmark.cmake)
include(cmake/Benchmark.cmake)
# Set up install.
INCLUDE(cmake/Install.cmake)
include(cmake/Install.cmake)
# Mac app.
INCLUDE(cmake/MacApp.cmake)
include(cmake/MacApp.cmake)
# Lint targets
# This could be implemented as target properties, but the script has the useful feature of only
# checking the currently-staged commands
# The generator expressions below rebuild the command line for the fishlib targets
# CMake does not support the "iquote" flag - https://gitlab.kitware.com/cmake/cmake/issues/15491
SET(LINT_ARGS "-D$<JOIN:$<TARGET_PROPERTY:fishlib,COMPILE_DEFINITIONS>, -D>" "-I$<JOIN:$<TARGET_PROPERTY:fishlib,INCLUDE_DIRECTORIES>, -I>")
ADD_CUSTOM_TARGET(lint
COMMAND build_tools/lint.fish -- ${LINT_ARGS}
set(LINT_ARGS "-D$<JOIN:$<TARGET_PROPERTY:fishlib,COMPILE_DEFINITIONS>, -D>" "-I$<JOIN:$<TARGET_PROPERTY:fishlib,INCLUDE_DIRECTORIES>, -I>")
add_custom_target(lint
COMMAND build_tools/lint.fish -p ${CMAKE_BINARY_DIR} -- ${LINT_ARGS}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
)
ADD_CUSTOM_TARGET(lint-all
COMMAND build_tools/lint.fish --all -- ${LINT_ARGS}
add_custom_target(lint-all
COMMAND build_tools/lint.fish --all -p ${CMAKE_BINARY_DIR} -- ${LINT_ARGS}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
)
INCLUDE(FeatureSummary)
FEATURE_SUMMARY(WHAT ALL)
include(FeatureSummary)
feature_summary(WHAT ALL)

View File

@@ -1,338 +0,0 @@
# 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. 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.
See the bottom of this document for help on installing the linting and style reformatting tools discussed in the following sections.
Fish source should limit the C++ features it uses to those available in C++11. It should not use exceptions.
Before introducing a new dependency, please make it optional with graceful failure if possible. Add
any new dependencies to the README.md under the *Running* and/or *Building* sections.
## 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
```
## Lint Free Code
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.
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
Once in a while the lint tools emit a false positive warning. For example, cppcheck might suggest a memory leak is present when that is not the case. To suppress that cppcheck warning you should insert a line like the following immediately prior to the line cppcheck warned about:
```
// cppcheck-suppress memleak // addr not really leaked
```
The explanatory portion of the suppression comment is optional. For other types of warnings replace "memleak" with the value inside the parenthesis (e.g., "nullPointerRedundantCheck") from a warning like the following:
```
[src/complete.cpp:1727]: warning (nullPointerRedundantCheck): Either the condition 'cmd_node' is redundant or there is possible null pointer dereference: cmd_node.
```
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.
## 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 `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 you've merged another person's change and want to check that it's style is acceptable. However, in that case it will run `clang-format` to ensure the entire file, not just the lines modified by the commit, conform to the style.
If you want to check the style of the entire code base run
```
build_tools/style.fish --all
```
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), make sure you have syntax and filetype functionality in `~/.vimrc`:
```
syntax enable
filetype plugin indent on
```
Then turn on some options for nicer display of fish scripts in `~/.vim/ftplugin/fish.vim`:
```
" Set up :make to use fish for syntax checking.
compiler fish
" Set this to have long lines wrap inside comments.
setlocal textwidth=79
" Enable folding of block structures in fish.
setlocal foldmethod=expr
```
If you use Emacs: Install [fish-mode](https://github.com/wwwjfy/emacs-fish) (also available in melpa and melpa-stable) and `(setq-default indent-tabs-mode nil)` for it (via a hook or in `use-package`s ":init" block). It can also be made to run fish_indent via e.g.
```elisp
(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
1. All fish scripts, such as those in the *share/functions* and *tests* directories, should be formatted using the `fish_indent` command.
1. Function names should be in all lowercase with words separated by underscores. Private functions should begin with an underscore. The first word should be `fish` if the function is unique to fish.
1. The first word of global variable names should generally be `fish` for public vars or `_fish` for private vars to minimize the possibility of name clashes with user defined vars.
## C++ Style Guide
1. The [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) forms the basis of the fish C++ style guide. There are two major deviations for the fish project. First, a four, rather than two, space indent. Second, line lengths up to 100, rather than 80, characters.
1. The `clang-format` command is authoritative with respect to indentation, whitespace around operators, etc.
1. All names in code should be `small_snake_case`. No Hungarian notation is used. The names for classes and structs should be followed by `_t`.
1. Always attach braces to the surrounding context.
1. Indent with spaces, not tabs and use four spaces per indent.
1. Document the purpose of a function or class with doxygen-style comment blocks. e.g.:
```
/**
* Sum numbers in a vector.
*
* @param values Container whose values are summed.
* @return sum of `values`, or 0.0 if `values` is empty.
*/
double sum(std::vector<double> & const values) {
...
}
*/
```
or
```
/// brief description of somefunction()
void somefunction() {
```
## Testing
The source code for fish includes a large collection of tests. If you 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 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).
### Local testing
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.
1. 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.
1. 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
Since developers sometimes forget to run the tests, it can be helpful to use git hooks (see githooks(5)) to automate it.
One possibility is a pre-push hook script like this one:
```sh
#!/bin/sh
#### A pre-push hook for the fish-shell project
# This will run the tests when a push to master is detected, and will stop that if the tests fail
# Save this as .git/hooks/pre-push and make it executable
protected_branch='master'
# Git gives us lines like "refs/heads/frombranch SOMESHA1 refs/heads/tobranch SOMESHA1"
# We're only interested in the branches
while read from _ to _; do
if [ "x$to" = "xrefs/heads/$protected_branch" ]; then
isprotected=1
fi
done
if [ "x$isprotected" = x1 ]; then
echo "Running tests before push to master"
make test
RESULT=$?
if [ $RESULT -ne 0 ]; then
echo "Tests failed for a push to master, we can't let you do that" >&2
exit 1
fi
fi
exit 0
```
This will check if the push is to the master branch and, if it is, only allow the push if running `make test` succeeds. In some circumstances it may be advisable to circumvent this check with `git push --no-verify`, but usually that isn't necessary.
To install the hook, place the code in a new file `.git/hooks/pre-push` and make it executable.
### Coverity Scan
We use Coverity's static analysis tool which offers free access to open source projects. While access to the tool itself is restricted, fish-shell organization members should know that they can login [here](https://scan.coverity.com/projects/fish-shell-fish-shell?tab=overview) with their GitHub account. Currently, tests are triggered upon merging the `master` branch into `coverity_scan_master`. Even if you are not a fish developer, you can keep an eye on our statistics there.
## Installing the Required Tools
### Installing the Linting Tools
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:
```
sudo apt-get install clang
sudo apt-get install oclint
sudo apt-get install cppcheck
```
### Installing the Reformatting Tools
Mac OS X:
```
brew install clang-format
```
Debian-based:
```
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
Fish uses the GNU gettext library to translate messages from English to other languages.
All non-debug messages output for user consumption should be marked for translation. In C++, this requires the use of the `_` (underscore) macro:
```
streams.out.append_format(_(L"%ls: There are no jobs\n"), argv[0]);
```
All messages in fish script must be enclosed in single or double quote characters. They must also be translated via a subcommand. This means that the following are **not** valid:
```
echo (_ hello)
_ "goodbye"
```
Above should be written like this instead:
```
echo (_ "hello")
echo (_ "goodbye")
```
Note that you can use either single or double quotes to enclose the message to be translated. You can also optionally include spaces after the opening parentheses and once again before the closing parentheses.
Creating and updating translations requires the Gettext tools, including `xgettext`, `msgfmt` and `msgmerge`. Translation sources are 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:
* 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`
Many tools are available for editing translation files, including command-line and graphical user interface programs.
Be cautious about blindly updating an existing translation file. Trivial changes to an existing message (eg changing the punctuation) will cause existing translations to be removed, since the tools do literal string matching. Therefore, in general, you need to carefully review any recommended deletions.
Read the [translations wiki](https://github.com/fish-shell/fish-shell/wiki/Translations) for more information.

499
CONTRIBUTING.rst Normal file
View File

@@ -0,0 +1,499 @@
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. 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.
See the bottom of this document for help on installing the linting and
style reformatting tools discussed in the following sections.
Fish source should limit the C++ features it uses to those available in
C++11. It should not use exceptions.
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.
Versioning
----------
The fish version is constructed by the *build_tools/git_version_gen.sh*
script. For developers the version is the branch name plus the output of
``git describe --always --dirty``. Normally the main part of the version
will be the closest annotated tag. Which itself is usually the most
recent release number (e.g., ``2.6.0``).
Include What You Use
--------------------
You should not depend on symbols being visible to a ``*.cpp`` module
from ``#include`` statements inside another header file. In other words
if your module does ``#include "common.h"`` and that header does
``#include "signal.h"`` your module should not assume the sub-include is
present. It should instead directly ``#include "signal.h"`` if it needs
any symbol from that header. That makes the actual dependencies much
clearer. It also makes it easy to modify the headers included by a
specific header file without having to worry that will break any module
(or header) that includes a particular header.
To help enforce this rule the ``make lint`` (and ``make lint-all``)
command will run the
`include-what-you-use <https://include-what-you-use.org/>`__ tool. You
can find the IWYU project on
`github <https://github.com/include-what-you-use/include-what-you-use>`__.
To install the tool on OS X youll need to add a
`formula <https://github.com/jasonmp85/homebrew-iwyu>`__ then install
it:
::
brew tap jasonmp85/iwyu
brew install iwyu
On Ubuntu you can install it via ``apt-get``:
::
sudo apt-get install iwyu
Lint Free Code
--------------
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.
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
~~~~~~~~~~~~~~~~~~~~~~~~~
Once in a while the lint tools emit a false positive warning. For
example, cppcheck might suggest a memory leak is present when that is
not the case. To suppress that cppcheck warning you should insert a line
like the following immediately prior to the line cppcheck warned about:
::
// cppcheck-suppress memleak // addr not really leaked
The explanatory portion of the suppression comment is optional. For
other types of warnings replace “memleak” with the value inside the
parenthesis (e.g., “nullPointerRedundantCheck”) from a warning like the
following:
::
[src/complete.cpp:1727]: warning (nullPointerRedundantCheck): Either the condition 'cmd_node' is redundant or there is possible null pointer dereference: cmd_node.
Suppressing oclint warnings is more complicated to describe so Ill
refer you to the `OCLint
HowTo <http://docs.oclint.org/en/latest/howto/suppress.html#annotations>`__
on the topic.
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 ``git-clang-format`` to
rewrite only the lines youre modifying.
If youve already committed your changes thats okay since it will then
check the files in the most recent commit. This can be useful after
youve merged another persons change and want to check that its style
is acceptable. However, in that case it will run ``clang-format`` to
ensure the entire file, not just the lines modified by the commit,
conform to the style.
If you want to check the style of the entire code base run
::
build_tools/style.fish --all
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 doesnt 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>`__,
make sure you have syntax and filetype functionality in ``~/.vimrc``:
::
syntax enable
filetype plugin indent on
Then turn on some options for nicer display of fish scripts in
``~/.vim/ftplugin/fish.vim``:
::
" Set up :make to use fish for syntax checking.
compiler fish
" Set this to have long lines wrap inside comments.
setlocal textwidth=79
" Enable folding of block structures in fish.
setlocal foldmethod=expr
If you use Emacs: Install
`fish-mode <https://github.com/wwwjfy/emacs-fish>`__ (also available in
melpa and melpa-stable) and ``(setq-default indent-tabs-mode nil)`` for
it (via a hook or in ``use-package``\ s “:init” block). It can also be
made to run fish_indent via e.g.
.. code:: elisp
(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 cant think of any legitimate reasons for exempting blocks of
code from clang-format.
Fish Script Style Guide
-----------------------
1. All fish scripts, such as those in the *share/functions* and *tests*
directories, should be formatted using the ``fish_indent`` command.
2. Function names should be in all lowercase with words separated by
underscores. Private functions should begin with an underscore. The
first word should be ``fish`` if the function is unique to fish.
3. The first word of global variable names should generally be ``fish``
for public vars or ``_fish`` for private vars to minimize the
possibility of name clashes with user defined vars.
C++ Style Guide
---------------
1. The `Google C++ Style
Guide <https://google.github.io/styleguide/cppguide.html>`__ forms
the basis of the fish C++ style guide. There are two major deviations
for the fish project. First, a four, rather than two, space indent.
Second, line lengths up to 100, rather than 80, characters.
2. The ``clang-format`` command is authoritative with respect to
indentation, whitespace around operators, etc.
3. All names in code should be ``small_snake_case``. No Hungarian
notation is used. The names for classes and structs should be
followed by ``_t``.
4. Always attach braces to the surrounding context.
5. Indent with spaces, not tabs and use four spaces per indent.
6. Document the purpose of a function or class with doxygen-style
comment blocks. e.g.:
::
/**
* Sum numbers in a vector.
*
* @param values Container whose values are summed.
* @return sum of `values`, or 0.0 if `values` is empty.
*/
double sum(std::vector<double> & const values) {
...
}
*/
or
::
/// brief description of somefunction()
void somefunction() {
Testing
-------
The source code for fish includes a large collection of tests. If you
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 dont run the tests on your machine, they will
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 dont reintroduce the bug).
Local testing
~~~~~~~~~~~~~
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 havent broken anything.
Thus it is a really good idea that you leverage Travis CI before making
a pull request to avoid potential embarrassment at breaking the build.
You will need to `fork the fish-shell repository on
GitHub <https://help.github.com/articles/fork-a-repo/>`__, then setup
Travis to test your changes before making a pull request.
1. `Sign in to Travis CI <https://travis-ci.org/auth>`__ with your
GitHub account, accepting the GitHub access permissions confirmation.
2. Once youre signed in and your repositories are synchronized, go to
your `profile page <https://travis-ci.org/profile>`__ and enable the
fish-shell repository.
3. Push your changes to GitHub.
Youll receive an email when the tests are complete telling you whether
or not any tests failed.
Youll find the configuration used to control Travis in the
``.travis.yml`` file.
Git hooks
~~~~~~~~~
Since developers sometimes forget to run the tests, it can be helpful to
use git hooks (see githooks(5)) to automate it.
One possibility is a pre-push hook script like this one:
.. code:: sh
#!/bin/sh
#### A pre-push hook for the fish-shell project
# This will run the tests when a push to master is detected, and will stop that if the tests fail
# Save this as .git/hooks/pre-push and make it executable
protected_branch='master'
# Git gives us lines like "refs/heads/frombranch SOMESHA1 refs/heads/tobranch SOMESHA1"
# We're only interested in the branches
while read from _ to _; do
if [ "x$to" = "xrefs/heads/$protected_branch" ]; then
isprotected=1
fi
done
if [ "x$isprotected" = x1 ]; then
echo "Running tests before push to master"
make test
RESULT=$?
if [ $RESULT -ne 0 ]; then
echo "Tests failed for a push to master, we can't let you do that" >&2
exit 1
fi
fi
exit 0
This will check if the push is to the master branch and, if it is, only
allow the push if running ``make test`` succeeds. In some circumstances
it may be advisable to circumvent this check with
``git push --no-verify``, but usually that isnt necessary.
To install the hook, place the code in a new file
``.git/hooks/pre-push`` and make it executable.
Coverity Scan
~~~~~~~~~~~~~
We use Coveritys static analysis tool which offers free access to open
source projects. While access to the tool itself is restricted,
fish-shell organization members should know that they can login
`here <https://scan.coverity.com/projects/fish-shell-fish-shell?tab=overview>`__
with their GitHub account. Currently, tests are triggered upon merging
the ``master`` branch into ``coverity_scan_master``. Even if you are not
a fish developer, you can keep an eye on our statistics there.
Installing the Required Tools
-----------------------------
Installing the Linting Tools
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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:
::
sudo apt-get install clang
sudo apt-get install oclint
sudo apt-get install cppcheck
Installing the Reformatting Tools
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mac OS X:
::
brew install clang-format
Debian-based:
::
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
--------------------
Fish uses the GNU gettext library to translate messages from English to
other languages.
All non-debug messages output for user consumption should be marked for
translation. In C++, this requires the use of the ``_`` (underscore)
macro:
::
streams.out.append_format(_(L"%ls: There are no jobs\n"), argv[0]);
All messages in fish script must be enclosed in single or double quote
characters. They must also be translated via a subcommand. This means
that the following are **not** valid:
::
echo (_ hello)
_ "goodbye"
Above should be written like this instead:
::
echo (_ "hello")
echo (_ "goodbye")
Note that you can use either single or double quotes to enclose the
message to be translated. You can also optionally include spaces after
the opening parentheses and once again before the closing parentheses.
Creating and updating translations requires the Gettext tools, including
``xgettext``, ``msgfmt`` and ``msgmerge``. Translation sources are
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: \* 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``
Many tools are available for editing translation files, including
command-line and graphical user interface programs.
Be cautious about blindly updating an existing translation file. Trivial
changes to an existing message (eg changing the punctuation) will cause
existing translations to be removed, since the tools do literal string
matching. Therefore, in general, you need to carefully review any
recommended deletions.
Read the `translations
wiki <https://github.com/fish-shell/fish-shell/wiki/Translations>`__ for
more information.

View File

@@ -1,7 +1,7 @@
Fish is a smart and user-friendly command line shell.
Copyright (C) 2005-2009 Axel Liljencrantz
Copyright (C) 2009-2019 fish-shell contributors
Copyright (C) 2009-2020 fish-shell contributors
fish is free software.

160
README.md
View File

@@ -1,160 +0,0 @@
[fish](https://fishshell.com/) - the friendly interactive shell [![Build Status](https://travis-ci.org/fish-shell/fish-shell.svg?branch=master)](https://travis-ci.org/fish-shell/fish-shell)
================================================
fish is a smart and user-friendly command line shell for macOS, Linux, 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 more on fish's design philosophy, see the [design document](https://fishshell.com/docs/current/design.html).
## Quick Start
fish generally works like other shells, like bash or zsh. A few important differences can be found at <https://fishshell.com/docs/current/tutorial.html> by searching for the 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](https://cdn.rawgit.com/rootnroll/library/assets/try.svg)](https://rootnroll.com/d/fish-shell/)
## Getting fish
### macOS
fish can be installed:
* using [Homebrew](http://brew.sh/): `brew install fish`
* using [MacPorts](https://www.macports.org/): `sudo port install fish`
* using the [installer from fishshell.com](https://fishshell.com/)
* as a [standalone app from fishshell.com](https://fishshell.com/)
### Packages for Linux
Packages for Debian, Fedora, openSUSE, and Red Hat Enterprise Linux/CentOS are available from the
[openSUSE Build
Service](https://software.opensuse.org/download.html?project=shells%3Afish&package=fish).
Packages for Ubuntu are available from the [fish
PPA](https://launchpad.net/~fish-shell/+archive/ubuntu/release-3), and can be installed using the
following commands:
```
sudo apt-add-repository ppa:fish-shell/release-3
sudo apt-get update
sudo apt-get install fish
```
Instructions for other distributions may be found at [fishshell.com](https://fishshell.com).
### Windows
- On Windows 10, fish can be installed under the WSL Windows Subsystem for Linux with `sudo apt install fish` or from source with the instructions below.
- Fish can also be installed on all versions of Windows using [Cygwin](https://cygwin.com/) (from the **Shells** category).
### Building from source
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* section for instructions.
## Running fish
Once installed, run `fish` from your current shell to try fish out!
### Dependencies
Running fish requires:
* curses or ncurses (preinstalled on most \*nix systems)
* 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, 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 `ul` and either `nroff` or `mandoc` for display
* 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
### Switching to fish
If you wish to use fish as your default shell, use the following command:
chsh -s /usr/local/bin/fish
`chsh` will prompt you for your password and change your default shell. (Substitute `/usr/local/bin/fish` with whatever path fish was installed to, if it differs.) Log out, then log in again for the changes to take effect.
Use the following command if fish isn't already added to `/etc/shells` to permit fish to be your login shell:
echo /usr/local/bin/fish | sudo tee -a /etc/shells
To switch your default shell back, you can run `chsh -s /bin/bash` (substituting `/bin/bash` with `/bin/tcsh` or `/bin/zsh` as appropriate).
## Building
### Dependencies
Compiling fish requires:
* a C++11 compiler (g++ 4.8 or later, or clang 3.3 or later)
* CMake (version 3.2 or later)
* a curses implementation such as ncurses (headers and libraries)
* 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.
### Building from source (all platforms) - Makefile generator
To install into `/usr/local`, run:
```bash
mkdir build; cd build
cmake ..
make
sudo make install
```
The install directory can be changed using the `-DCMAKE_INSTALL_PREFIX` parameter for `cmake`.
### Building from source (macOS) - Xcode
```bash
mkdir build; cd build
cmake .. -G Xcode
```
An Xcode project will now be available in the `build` subdirectory. You can open it with Xcode,
or run the following to build and install in `/usr/local`:
```bash
xcodebuild
xcodebuild -scheme install
```
The install directory can be changed using the `-DCMAKE_INSTALL_PREFIX` parameter for `cmake`.
### Help, it didn't build!
If fish reports that it could not find curses, try installing a curses development package and build again.
On Debian or Ubuntu you want:
sudo apt-get install build-essential cmake ncurses-dev libncurses5-dev libpcre2-dev gettext
On RedHat, CentOS, or Amazon EC2:
sudo yum install ncurses-devel
## Contributing Changes to the Code
See the [Guide for Developers](CONTRIBUTING.md).
## 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 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).

238
README.rst Normal file
View File

@@ -0,0 +1,238 @@
`fish <https://fishshell.com/>`__ - the friendly interactive shell |Build Status|
=================================================================================
fish is a smart and user-friendly command line shell for macOS, Linux,
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 more on fishs design philosophy, see the `design
document <https://fishshell.com/docs/current/design.html>`__.
Quick Start
-----------
fish generally works like other shells, like bash or zsh. A few
important differences can be found at
https://fishshell.com/docs/current/tutorial.html by searching for the
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
------------
macOS
~~~~~
fish can be installed:
- using `Homebrew <http://brew.sh/>`__: ``brew install fish``
- using `MacPorts <https://www.macports.org/>`__:
``sudo port install fish``
- using the `installer from fishshell.com <https://fishshell.com/>`__
- as a `standalone app from fishshell.com <https://fishshell.com/>`__
Packages for Linux
~~~~~~~~~~~~~~~~~~
Packages for Debian, Fedora, openSUSE, and Red Hat Enterprise
Linux/CentOS are available from the `openSUSE Build
Service <https://software.opensuse.org/download.html?project=shells%3Afish&package=fish>`__.
Packages for Ubuntu are available from the `fish
PPA <https://launchpad.net/~fish-shell/+archive/ubuntu/release-3>`__,
and can be installed using the following commands:
::
sudo apt-add-repository ppa:fish-shell/release-3
sudo apt-get update
sudo apt-get install fish
Instructions for other distributions may be found at
`fishshell.com <https://fishshell.com>`__.
Windows
~~~~~~~
- On Windows 10, fish can be installed under the WSL Windows Subsystem
for Linux with the instructions for the appropriate distribution
listed above under “Packages for Linux”, or from source with the
instructions below.
- Fish can also be installed on all versions of Windows using
`Cygwin <https://cygwin.com/>`__ (from the **Shells** category).
Building from source
~~~~~~~~~~~~~~~~~~~~
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* section for instructions.
Running fish
------------
Once installed, run ``fish`` from your current shell to try fish out!
Dependencies
~~~~~~~~~~~~
Running fish requires:
- curses or ncurses (preinstalled on most \*nix systems)
- 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, 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 ``ul`` and either ``nroff`` or ``mandoc`` for
display
- 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
Switching to fish
~~~~~~~~~~~~~~~~~
If you wish to use fish as your default shell, use the following
command:
::
chsh -s /usr/local/bin/fish
``chsh`` will prompt you for your password and change your default
shell. (Substitute ``/usr/local/bin/fish`` with whatever path fish was
installed to, if it differs.) Log out, then log in again for the changes
to take effect.
Use the following command if fish isnt already added to ``/etc/shells``
to permit fish to be your login shell:
::
echo /usr/local/bin/fish | sudo tee -a /etc/shells
To switch your default shell back, you can run ``chsh -s /bin/bash``
(substituting ``/bin/bash`` with ``/bin/tcsh`` or ``/bin/zsh`` as
appropriate).
Building
--------
.. _dependencies-1:
Dependencies
~~~~~~~~~~~~
Compiling fish requires:
- a C++11 compiler (g++ 4.8 or later, or clang 3.3 or later)
- CMake (version 3.2 or later)
- a curses implementation such as ncurses (headers and libraries)
- 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.
Building from source (all platforms) - Makefile generator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To install into ``/usr/local``, run:
.. code:: bash
mkdir build; cd build
cmake ..
make
sudo make install
The install directory can be changed using the
``-DCMAKE_INSTALL_PREFIX`` parameter for ``cmake``.
Building from source (macOS) - Xcode
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: bash
mkdir build; cd build
cmake .. -G Xcode
An Xcode project will now be available in the ``build`` subdirectory.
You can open it with Xcode, or run the following to build and install in
``/usr/local``:
.. code:: bash
xcodebuild
xcodebuild -scheme install
The install directory can be changed using the
``-DCMAKE_INSTALL_PREFIX`` parameter for ``cmake``.
Help, it didnt build!
~~~~~~~~~~~~~~~~~~~~~~
If fish reports that it could not find curses, try installing a curses
development package and build again.
On Debian or Ubuntu you want:
::
sudo apt-get install build-essential cmake ncurses-dev libncurses5-dev libpcre2-dev gettext
On RedHat, CentOS, or Amazon EC2:
::
sudo yum install ncurses-devel
Contributing Changes to the Code
--------------------------------
See the `Guide for Developers <CONTRIBUTING.rst>`__.
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
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://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/

View File

@@ -1,5 +1,5 @@
function alias --description 'Creates a function wrapping a command'
set -l options 'h/help' 's/save'
set -l options h/help s/save
argparse -n alias --max-args=2 $options -- $argv
or return

View File

@@ -5,31 +5,31 @@
#
# Usage: ./diff_profiles.fish profile1.log profile2.log > profile_diff.log
set profile1 (cat $argv[1])
set profile2 (cat $argv[2])
set -l profile1 (cat $argv[1])
set -l profile2 (cat $argv[2])
set line_no 0
while set next_line_no (math $line_no + 1) && set -q profile1[$next_line_no] && set -q profile2[$next_line_no]
set -l line_no 0
while set -l next_line_no (math $line_no + 1) && set -q profile1[$next_line_no] && set -q profile2[$next_line_no]
set line_no $next_line_no
set line1 $profile1[$line_no]
set line2 $profile2[$line_no]
set -l line1 $profile1[$line_no]
set -l line2 $profile2[$line_no]
if not string match -qr '^\d+\t\d+' $line1
echo $line1
continue
end
set results1 (string match -r '^(\d+)\t(\d+)\s+(.*)' $line1)
set results2 (string match -r '^(\d+)\t(\d+)\s+(.*)' $line2)
set -l results1 (string match -r '^(\d+)\t(\d+)\s+(.*)' $line1)
set -l results2 (string match -r '^(\d+)\t(\d+)\s+(.*)' $line2)
# times from both files
set time1 $results1[2..3]
set time2 $results2[2..3]
set -l time1 $results1[2..3]
set -l time2 $results2[2..3]
# leftover from both files
set remainder1 $results1[4]
set remainder2 $results2[4]
set -l remainder1 $results1[4]
set -l remainder2 $results2[4]
if not string match -q -- $remainder1 $remainder2
echo Mismatch on line $line_no:

View File

@@ -4,7 +4,7 @@
# for object files in this directory.
# This was written for macOS nm.
set FISH_SOURCE_DIR $argv[1]
set -l FISH_SOURCE_DIR $argv[1]
if not test -d "$FISH_SOURCE_DIR"
echo "FISH_SOURCE_DIR not given"
exit 1
@@ -20,8 +20,8 @@ set -g whitelist \
# In our nm regex, we are interested in data (dD) and bss (bB) segments.
set -g nm_regex '^([^ ]+) ([dDbB])'
set total_globals 0
set boring_files \
set -l total_globals 0
set -l boring_files \
fish_key_reader.cpp.o \
fish_tests.cpp.o \
fish_indent.cpp.o \
@@ -29,7 +29,7 @@ set boring_files \
# return if we should ignore the given symbol name
function should_ignore
set symname $argv[1]
set -l symname $argv[1]
string match -q '*guard variable for*' $symname
and return 0
contains $symname $whitelist
@@ -39,16 +39,14 @@ end
# echo a cleaned-up symbol name, e.g. replacing template gunk
function cleanup_syname
set symname $argv[1]
set -l symname $argv[1]
set symname (string replace --all 'std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >' 'wcstring' $symname)
set symname (string replace --all 'std::__1::vector<wcstring, std::__1::allocator<wcstring > >' 'wcstring_list_t' $symname)
echo $symname
end
# Output the declaration for a symbol name in a given file.
function print_decl
set -l objfile $argv[1]
set -l symname $argv[2]
function print_decl -a FISH_SOURCE_DIR objfile symname
set -l varname (string split '::' $symname)[-1]
set -l srcfile (basename $objfile .o)
set -l srcpath $FISH_SOURCE_DIR/src/$srcfile
@@ -61,7 +59,7 @@ function print_decl
end
# Guess the variable as the first usage of the name.
# Strip everything after the first =.
set vardecl (egrep -m 1 " $varname\\b" $srcpath | cut -f -1 -d '=' | string trim)
set -l vardecl (egrep -m 1 " $varname\\b" $srcpath | cut -f -1 -d '=' | string trim)
if test -z "$vardecl"
echo "COULD_NOT_FIND_$varname"
return 1
@@ -78,7 +76,7 @@ function decl_is_threadsafe
and return 0
# Ordinary types indicating a safe variable.
set safes relaxed_atomic_bool_t std::mutex std::condition_variable std::once_flag sig_atomic_t
set -l safes relaxed_atomic_bool_t std::mutex std::condition_variable std::once_flag sig_atomic_t
for safe in $safes
string match -q "*$safe*" $vardecl
and return 0
@@ -93,17 +91,17 @@ function decl_is_threadsafe
end
for file in ./**.o
set filename (basename $file)
set -l filename (basename $file)
# Skip boring files.
contains $filename $boring_files
and continue
for line in (nm -p -P -U $file | egrep $nm_regex)
set matches (string match --regex $nm_regex -- $line)
set -l matches (string match --regex $nm_regex -- $line)
or continue
set symname (cleanup_syname (echo $matches[2] | c++filt))
set -l symname (cleanup_syname (echo $matches[2] | c++filt))
should_ignore $symname
and continue
set vardecl (print_decl $filename $symname)
set -l vardecl (print_decl $FISH_SOURCE_DIR $filename $symname)
decl_is_threadsafe $vardecl
and continue
echo $filename $symname $matches[3] ":" $vardecl

View File

@@ -16,11 +16,11 @@ xgettext -k -k_ -kN_ -LC++ --no-wrap -o messages.pot src/*.cpp src/*.h
# This regex handles descriptions for `complete` and `function` statements. These messages are not
# particularly important to translate. Hence the "implicit" label.
set implicit_regex '(?:^| +)(?:complete|function).*? (?:-d|--description) (([\'"]).+?(?<!\\\\)\\2).*'
set -l implicit_regex '(?:^| +)(?:complete|function).*? (?:-d|--description) (([\'"]).+?(?<!\\\\)\\2).*'
# This regex handles explicit requests to translate a message. These are more important to translate
# than messages which should be implicitly translated.
set explicit_regex '.*\( *_ (([\'"]).+?(?<!\\\\)\\2) *\).*'
set -l explicit_regex '.*\( *_ (([\'"]).+?(?<!\\\\)\\2) *\).*'
rm -r /tmp/fish

View File

@@ -6,14 +6,14 @@
# We don't include "missingInclude" as that doesn't find our config.h.
# Missing includes will quickly be found by... compiling the thing anyway.
set cppchecks warning,performance,portability,information #,missingInclude
set cppcheck_args
set c_files
set all no
set kernel_name (uname -s)
set machine_type (uname -m)
set -l cppchecks warning,performance,portability,information #,missingInclude
set -l cppcheck_args
set -l c_files
set -l all no
set -l kernel_name (uname -s)
set -l machine_type (uname -m)
argparse a/all -- $argv
argparse a/all p/project= -- $argv
# We only want -D and -I options to be passed thru to cppcheck.
for arg in $argv
@@ -31,7 +31,7 @@ end
# be harmless everywhere else.
set cppcheck_args $cppcheck_args -I /usr/include -I .
if test "$machine_type" = "x86_64"
if test "$machine_type" = x86_64
set cppcheck_args -D__x86_64__ -D__LP64__ $cppcheck_args
end
@@ -42,7 +42,7 @@ else
# We haven't been asked to lint all the source. If there are uncommitted
# changes lint those, else lint the files in the most recent commit.
# Select (cached files) (modified but not cached, and untracked files)
set files (git diff-index --cached HEAD --name-only)
set -l files (git diff-index --cached HEAD --name-only)
set files $files (git ls-files --exclude-standard --others --modified)
if not set -q files[1]
# No pending changes so lint the files in the most recent commit.
@@ -117,6 +117,14 @@ if set -q c_files[1]
# output will expect those messages to be written to stdout.
oclint $c_files -- $argv 2>&1
end
if type -q clang-tidy; and set -q _flag_project
echo
echo ========================================
echo Running clang-tidy
echo ========================================
clang-tidy -p $_flag_project $c_files
end
else
echo
echo 'WARNING: No C/C++ files to check'

View File

@@ -1,6 +1,6 @@
#! /usr/bin/env fish
set TAG $argv[1]
set -l TAG $argv[1]
if test -z "$TAG"
echo "Tag name required."
@@ -12,8 +12,8 @@ if not contains -- $TAG (git tag)
exit 1
end
set committers_to_tag (mktemp)
set committers_from_tag (mktemp)
set -l committers_to_tag (mktemp)
set -l committers_from_tag (mktemp)
# You might think it would be better to case-insensitively sort/compare the names
# to produce a more natural-looking list.

View File

@@ -6,6 +6,8 @@ from __future__ import unicode_literals
from __future__ import print_function
import argparse
from collections import deque
import datetime
import io
import re
import shlex
@@ -32,6 +34,8 @@ class Config(object):
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 """
@@ -66,6 +70,34 @@ def output(*args):
print("".join(args) + "\n")
import unicodedata
def esc(m):
map = {
"\n": "\\n",
"\\": "\\\\",
"'": "\\'",
'"': '\\"',
"\a": "\\a",
"\b": "\\b",
"\f": "\\f",
"\r": "\\r",
"\t": "\\t",
"\v": "\\v",
}
if m in map:
return map[m]
if unicodedata.category(m)[0] == "C":
return "\\x{:02x}".format(ord(m))
else:
return m
def escape_string(s):
return "".join(esc(ch) for ch in s)
class CheckerError(Exception):
"""Exception subclass for check line parsing.
@@ -117,13 +149,14 @@ class RunCmd(object):
class TestFailure(object):
def __init__(self, line, check, testrun, after = None):
def __init__(self, line, check, testrun, before=None, after=None):
self.line = line
self.check = check
self.testrun = testrun
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
@@ -180,12 +213,17 @@ class TestFailure(object):
" additional output on stderr:{error_annotation_lineno}:",
" {BOLD}{error_annotation}{RESET}",
]
if self.after:
if self.before:
fields["before_output"] = " ".join(self.before)
fields["additional_output"] = " ".join(self.after[:afterlines])
fmtstrs += [
" additional output:",
" 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)
@@ -229,6 +267,8 @@ class TestRun(object):
# Reverse our lines and checks so we can pop off the end.
lineq = lines[::-1]
checkq = checks[::-1]
# 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]
@@ -236,14 +276,26 @@ class TestRun(object):
# This line matched this checker, continue on.
lineq.pop()
checkq.pop()
before.append(line)
elif line.is_empty_space():
# Skip all whitespace input lines.
lineq.pop()
else:
# Failed to match.
lineq.pop()
line.text = escape_string(line.text.strip()) + "\n"
# Add context, ignoring empty lines.
return TestFailure(line, check, self, after = [line.text for line in lineq[::-1] if not line.is_empty_space()])
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()
@@ -440,19 +492,28 @@ def get_argparse():
parser.add_argument(
"-p",
"--progress",
action='store_true',
dest='progress',
action="store_true",
dest="progress",
help="Show the files to be checked",
default=False,
)
parser.add_argument("file", nargs="+", help="File to check")
parser.add_argument(
"-A", "--after",
"-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
@@ -462,23 +523,37 @@ def main():
def_subs = {"%": "%"}
def_subs.update(parse_subs(args.substitute))
success = True
failure_count = 0
config = Config()
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:
fields["path"] = path
if config.progress:
print("Testing file {path} ... ".format(**fields), end='')
print("Testing file {path} ... ".format(**fields), end="")
sys.stdout.flush()
subs = def_subs.copy()
subs["s"] = path
starttime = datetime.datetime.now()
if not check_path(path, subs, config, TestFailure.print_message):
success = False
failure_count += 1
elif config.progress:
print("{GREEN}ok{RESET}".format(**fields))
sys.exit(0 if success else 1)
endtime = datetime.datetime.now()
duration_ms = round((endtime - starttime).total_seconds() * 1000)
print(
"{GREEN}ok{RESET} ({duration} ms)".format(
duration=duration_ms, **fields
)
)
sys.exit(failure_count)
if __name__ == "__main__":

99
build_tools/mac_notarize.sh Executable file
View File

@@ -0,0 +1,99 @@
#!/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
}
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
}
INPUT=$1
AC_USER=$2
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"
unzip -q "$INPUT" -d "$TMPDIR"
# Force glob expansion.
STAPLE_TARGET="$TMPDIR"/*
STAPLE_TARGET=$(echo $STAPLE_TARGET)
else
STAPLE_TARGET="$INPUT"
fi
echo "Stapling $STAPLE_TARGET"
xcrun stapler staple "$STAPLE_TARGET"
if test "$ext" = "zip"; then
# Zip it back up.
INPUT_FULL=$(realpath "$INPUT")
rm -f "$INPUT"
cd "$(dirname "$STAPLE_TARGET")"
zip -r -q "$INPUT_FULL" $(basename "$STAPLE_TARGET")
fi
fi
echo "Processed $INPUT"
if test "$ext" = "zip"; then
spctl -a -v "$STAPLE_TARGET"
fi

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/usr/bin/env bash
# Script to produce an OS X installer .pkg and .app(.zip)
@@ -17,19 +17,23 @@ set -x
#Exit on error
set -e
# 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)
SRC_DIR=$PWD
OUTPUT_PATH=${FISH_ARTEFACT_PATH:-~/fish_built}
mkdir -p "$PKGDIR/build" "$PKGDIR/root" "$PKGDIR/intermediates" "$PKGDIR/dst"
{ cd "$PKGDIR/build" && cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo "$SRC_DIR" && make -j 4 && env DESTDIR="$PKGDIR/root/" make install; }
pkgbuild --scripts 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 build_tools/osx_distribution.xml --resources build_tools/osx_package_resources/ "$OUTPUT_PATH/fish-$VERSION.pkg"
{ 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"
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 fish_macapp && zip -r "$OUTPUT_PATH/fish-$VERSION.app.zip" fish.app; }
{ cd "$PKGDIR/build" && make signed_fish_macapp && zip -r "$OUTPUT_PATH/fish-$VERSION.app.zip" fish.app; }
rm -r "$PKGDIR"

View File

@@ -42,7 +42,7 @@ prefix="fish-$VERSION"
path=${FISH_ARTEFACT_PATH:-~/fish_built}/$prefix.tar
# Clean up stuff we've written before
rm -f "$path" "$path".gz
rm -f "$path" "$path".xz
# git starts the archive
git archive --format=tar --prefix="$prefix"/ HEAD > "$path"
@@ -63,9 +63,9 @@ $TAR_APPEND version
cd -
rm -r "$PREFIX_TMPDIR"
# gzip it
gzip "$path"
# xz it
xz "$path"
# Output what we did, and the sha1 hash
echo "Tarball written to $path".gz
openssl dgst -sha256 "$path".gz
echo "Tarball written to $path".xz
openssl dgst -sha256 "$path".xz

View File

@@ -0,0 +1,319 @@
"""pexpect_helper provides a wrapper around the pexpect module.
This module exposes a single class SpawnedProc, which wraps pexpect.spawn().
This exposes a pseudo-tty, which fish or another process may talk to.
The send() function may be used to send data to fish, and the expect_* family
of functions may be used to match what is output to the tty.
Example usage:
sp = SpawnedProc() # this launches fish
sp.expect_prompt() # wait for a prompt
sp.sendline("echo hello world")
sp.expect_prompt("hello world")
"""
from __future__ import print_function
import inspect
import os
import os.path
import re
import sys
import time
import pexpect
# Default timeout for failing to match.
TIMEOUT_SECS = 5
def get_prompt_re(counter):
""" Return a regular expression for matching a with a given prompt counter. """
return re.compile(
r"""(?:\r\n?|^) # beginning of line
(?:\[.\]\ )? # optional vi mode prompt
"""
+ (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. """
callstack = inspect.getouterframes(inspect.currentframe())
for f in callstack:
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. """
res = []
for c in s:
if c == "\n":
res.append("\\n")
elif c == "\r":
res.append("\\r")
elif c == "\t":
res.append("\\t")
elif c.isprintable():
res.append(c)
else:
res.append("\\x{:02x}".format(ord(c)))
return "".join(res)
def pexpect_error_type(err):
""" Return a human-readable description of a pexpect error type. """
if isinstance(err, pexpect.EOF):
return "EOF"
elif isinstance(err, pexpect.TIMEOUT):
return "timeout"
else:
return "unknown error"
class Message(object):
""" Some text either sent-to or received-from the spawned proc.
Attributes:
dir: the message direction, either DIR_INPUT or DIR_OUTPUT
filename: the name of the file from which the message was sent
text: the text of the messages
when: a timestamp of when the message was sent
"""
# Input is input into fish shell ("sent data").
DIR_INPUT = " INPUT"
# Output means output from fish shell ("received data").
DIR_OUTPUT = "OUTPUT"
MODULE = sys.modules[__name__]
def __init__(self, dir, text, when):
""" Construct from a direction, message text and timestamp. """
self.dir = dir
self.filename, self.lineno, _ = get_callsite()
self.text = text
self.when = when
@staticmethod
def sent_input(text, when):
""" 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 Message(Message.DIR_OUTPUT, text, when)
class SpawnedProc(object):
""" A process, talking to our ptty. This wraps pexpect.spawn.
Attributes:
colorize: whether error messages should have ANSI color escapes
messages: list of Message sent and received, in-order
start_time: the timestamp of the first message, or None if none yet
spawn: the pexpect.spawn value
prompt_counter: the index of the prompt. This cooperates with the fish_prompt
function to ensure that each printed prompt is distinct.
"""
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.
"""
if name not in env:
raise ValueError("'name' variable not found in environment" % name)
exe_path = env.get(name)
self.colorize = sys.stdout.isatty()
self.messages = []
self.start_time = None
self.spawn = pexpect.spawn(exe_path, env=env, encoding="utf-8", timeout=timeout)
self.spawn.delaybeforesend = None
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. """
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.
"""
res = self.spawn.send(s)
when = self.time_since_first_message()
self.messages.append(Message.sent_input(s, when))
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.
"""
return self.send(s + os.linesep)
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:
res = self.spawn.expect(pat, **kwargs)
when = self.time_since_first_message()
self.messages.append(
Message.received_output(self.spawn.match.group(), when)
)
return res
except pexpect.ExceptionPexpect as err:
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. """
return self.expect_re(re.escape(s), **kwargs)
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)
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.
"""
colors = self.colors()
failtype = pexpect_error_type(err)
fmtkeys = {"failtype": failtype, "pat": escape(pat)}
fmtkeys.update(**colors)
filename, lineno, code_context = get_callsite()
fmtkeys["filename"] = filename
fmtkeys["lineno"] = lineno
fmtkeys["code"] = "\n".join(code_context)
if unmatched:
print(
"{RED}Error: {NORMAL}{BOLD}{unmatched}{RESET}".format(
unmatched=unmatched, **fmtkeys
)
)
print(
"{RED}Failed to match pattern:{NORMAL} {BOLD}{pat}{RESET}".format(**fmtkeys)
)
print(
"{filename}:{lineno}: {BOLD}{failtype}{RESET} from {code}".format(**fmtkeys)
)
print("")
print("{CYAN}Escaped buffer:{RESET}".format(**colors))
print(escape(self.spawn.before))
print("")
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 5 messages.
print("Last 5 messages:")
delta = None
for m in self.messages[-5:]:
etext = escape(m.text)
timestamp = m.when * 1000.0
# Use relative timestamps and add a sign.
# This assumes a max length of 10^10 milliseconds (115 days) for the initial timestamp,
# and 11.5 days for the delta.
if delta:
timestamp -= delta
timestampstr = "{timestamp:+10.2f} ms".format(timestamp=timestamp)
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,
timestampstr=timestampstr,
filename=m.filename,
lineno=m.lineno,
etext=etext,
**colors
)
)
print("")
sys.exit(1)
def sleep(self, secs):
""" Cover over time.sleep(). """
time.sleep(secs)
def colors(self):
""" 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 "\033[%dm" % n if self.colorize else ""
return {
"RESET": ansic(0),
"BOLD": ansic(1),
"NORMAL": ansic(39),
"BLACK": ansic(30),
"RED": ansic(31),
"GREEN": ansic(32),
"YELLOW": ansic(33),
"BLUE": ansic(34),
"MAGENTA": ansic(35),
"CYAN": ansic(36),
"LIGHTGRAY": ansic(37),
"DARKGRAY": ansic(90),
"LIGHTRED": ansic(91),
"LIGHTGREEN": ansic(92),
"LIGHTYELLOW": ansic(93),
"LIGHTBLUE": ansic(94),
"LIGHTMAGENTA": ansic(95),
"LIGHTCYAN": ansic(96),
"WHITE": ansic(97),
}

View File

@@ -3,13 +3,13 @@
# This runs C++ files and fish scripts (*.fish) through their respective code
# formatting programs.
#
set git_clang_format no
set c_files
set fish_files
set python_files
set all no
set -l git_clang_format no
set -l c_files
set -l fish_files
set -l python_files
set -l all no
if test "$argv[1]" = "--all"
if test "$argv[1]" = --all
set all yes
set -e argv[1]
end
@@ -20,7 +20,7 @@ if set -q argv[1]
end
if test $all = yes
set files (git status --porcelain --short --untracked-files=all | sed -e 's/^ *[^ ]* *//')
set -l files (git status --porcelain --short --untracked-files=all | sed -e 's/^ *[^ ]* *//')
if set -q files[1]
echo
echo You have uncommitted changes. Cowardly refusing to restyle the entire code base.
@@ -34,7 +34,7 @@ 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.
# Select (cached files) (modified but not cached, and untracked files)
set files (git diff-index --cached HEAD --name-only) (git ls-files --exclude-standard --others --modified)
set -l files (git diff-index --cached HEAD --name-only) (git ls-files --exclude-standard --others --modified)
if set -q files[1]
set git_clang_format yes
else

View File

@@ -1,6 +1,6 @@
# Support for benchmarking fish.
ADD_CUSTOM_TARGET(benchmark
add_custom_target(benchmark
COMMAND ${CMAKE_SOURCE_DIR}/benchmarks/driver.sh $<TARGET_FILE:fish>
USES_TERMINAL
)

View File

@@ -3,153 +3,154 @@
# and CMAKE_REQUIRED_INCLUDES
# `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)
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE=1)
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()
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()
# Try using CMake's own logic to locate curses/ncurses
FIND_PACKAGE(Curses)
IF(NOT ${CURSES_FOUND})
find_package(Curses)
if(NOT ${CURSES_FOUND})
# CMake has trouble finding platform-specific system libraries
# installed to multiarch paths (e.g. /usr/lib/x86_64-linux-gnu)
# if not symlinked or passed in as a manual define.
MESSAGE("Falling back to pkg-config for (n)curses detection")
INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(CURSES REQUIRED ncurses curses)
SET(CURSES_CURSES_LIBRARY ${CURSES_LIBRARIES})
SET(CURSES_LIBRARY ${CURSES_LIBRARIES})
ENDIF()
message("Falling back to pkg-config for (n)curses detection")
include(FindPkgConfig)
pkg_search_module(CURSES REQUIRED ncurses curses)
set(CURSES_CURSES_LIBRARY ${CURSES_LIBRARIES})
set(CURSES_LIBRARY ${CURSES_LIBRARIES})
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)
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.
if (CMAKE_HOST_SYSTEM_VERSION MATCHES ".*-Microsoft")
SET(WSL 1)
set(WSL 1)
endif()
# Set up the config.h file.
SET(PACKAGE_NAME "fish")
SET(PACKAGE_TARNAME "fish")
INCLUDE(CheckCXXSymbolExists)
INCLUDE(CheckIncludeFileCXX)
INCLUDE(CheckIncludeFiles)
INCLUDE(CheckStructHasMember)
INCLUDE(CheckCXXSourceCompiles)
INCLUDE(CheckTypeSize)
INCLUDE(CMakePushCheckState)
CHECK_CXX_SYMBOL_EXISTS(backtrace_symbols execinfo.h HAVE_BACKTRACE_SYMBOLS)
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)
set(PACKAGE_NAME "fish")
set(PACKAGE_TARNAME "fish")
include(CheckCXXSymbolExists)
include(CheckIncludeFileCXX)
include(CheckIncludeFiles)
include(CheckStructHasMember)
include(CheckCXXSourceCompiles)
include(CheckTypeSize)
include(CMakePushCheckState)
check_cxx_symbol_exists(backtrace_symbols execinfo.h HAVE_BACKTRACE_SYMBOLS)
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)
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})
SET(HAVE_NCURSES_CURSES_H ${CURSES_HAVE_NCURSES_CURSES_H})
SET(HAVE_NCURSES_H ${CURSES_HAVE_NCURSES_H})
IF(HAVE_CURSES_H)
CHECK_INCLUDE_FILES("curses.h;term.h" HAVE_TERM_H)
ENDIF()
IF(NOT HAVE_TERM_H)
CHECK_INCLUDE_FILE_CXX("ncurses/term.h" HAVE_NCURSES_TERM_H)
ENDIF()
CHECK_INCLUDE_FILE_CXX(siginfo.h HAVE_SIGINFO_H)
CHECK_INCLUDE_FILE_CXX(spawn.h HAVE_SPAWN_H)
CHECK_STRUCT_HAS_MEMBER("struct stat" st_ctime_nsec "sys/stat.h" HAVE_STRUCT_STAT_ST_CTIME_NSEC
check_cxx_symbol_exists(mkostemp "stdlib.h;unistd.h" HAVE_MKOSTEMP)
set(HAVE_CURSES_H ${CURSES_HAVE_CURSES_H})
set(HAVE_NCURSES_CURSES_H ${CURSES_HAVE_NCURSES_CURSES_H})
set(HAVE_NCURSES_H ${CURSES_HAVE_NCURSES_H})
if(HAVE_CURSES_H)
check_include_files("curses.h;term.h" HAVE_TERM_H)
endif()
if(NOT HAVE_TERM_H)
check_include_file_cxx("ncurses/term.h" HAVE_NCURSES_TERM_H)
endif()
check_include_file_cxx(siginfo.h HAVE_SIGINFO_H)
check_include_file_cxx(spawn.h HAVE_SPAWN_H)
check_struct_has_member("struct stat" st_ctime_nsec "sys/stat.h" HAVE_STRUCT_STAT_ST_CTIME_NSEC
LANGUAGE CXX)
CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtimespec.tv_nsec "sys/stat.h"
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
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)
CHECK_INCLUDE_FILES("sys/types.h;sys/sysctl.h" HAVE_SYS_SYSCTL_H)
CHECK_INCLUDE_FILE_CXX(termios.h HAVE_TERMIOS_H) # Needed for TIOCGWINSZ
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)
check_include_files("sys/types.h;sys/sysctl.h" HAVE_SYS_SYSCTL_H)
check_include_file_cxx(termios.h HAVE_TERMIOS_H) # Needed for TIOCGWINSZ
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)
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()
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()
# `xlocale.h` is required to find `wcstod_l` in `wchar.h` under FreeBSD,
# but it's not present under Linux.
CHECK_INCLUDE_FILES("xlocale.h" HAVE_XLOCALE_H)
IF(HAVE_XLOCALE_H)
LIST(APPEND WCSTOD_L_INCLUDES "xlocale.h")
ENDIF()
LIST(APPEND WCSTOD_L_INCLUDES "wchar.h")
CHECK_CXX_SYMBOL_EXISTS(wcstod_l "${WCSTOD_L_INCLUDES}" HAVE_WCSTOD_L)
check_include_files("xlocale.h" HAVE_XLOCALE_H)
if(HAVE_XLOCALE_H)
list(APPEND WCSTOD_L_INCLUDES "xlocale.h")
endif()
list(APPEND WCSTOD_L_INCLUDES "wchar.h")
check_cxx_symbol_exists(wcstod_l "${WCSTOD_L_INCLUDES}" HAVE_WCSTOD_L)
CHECK_CXX_SYMBOL_EXISTS(_sys_errs stdlib.h HAVE__SYS__ERRS)
check_cxx_symbol_exists(_sys_errs stdlib.h HAVE__SYS__ERRS)
CMAKE_PUSH_CHECK_STATE()
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(STRUCT_WINSIZE GREATER -1 AND HAVE_TIOCGWINSZ EQUAL 1)
SET(HAVE_WINSIZE 1)
ENDIF()
CMAKE_POP_CHECK_STATE()
cmake_push_check_state()
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(STRUCT_WINSIZE GREATER -1 AND HAVE_TIOCGWINSZ EQUAL 1)
set(HAVE_WINSIZE 1)
endif()
cmake_pop_check_state()
CHECK_TYPE_SIZE("wchar_t[8]" WCHAR_T_BITS LANGUAGE CXX)
check_type_size("wchar_t[8]" WCHAR_T_BITS LANGUAGE CXX)
# Solaris, NetBSD and X/Open-conforming systems have a fixed-args tparm
SET(TPARM_INCLUDES)
IF(HAVE_NCURSES_H)
SET(TPARM_INCLUDES "${TPARM_INCLUDES}#include <ncurses.h>\n")
ELSEIF(HAVE_NCURSES_CURSES_H)
SET(TPARM_INCLUDES "${TPARM_INCLUDES}#include <ncurses/curses.h>\n")
ELSE()
SET(TPARM_INCLUDES "${TPARM_INCLUDES}#include <curses.h>\n")
ENDIF()
set(TPARM_INCLUDES)
if(HAVE_NCURSES_H)
set(TPARM_INCLUDES "${TPARM_INCLUDES}#include <ncurses.h>\n")
elseif(HAVE_NCURSES_CURSES_H)
set(TPARM_INCLUDES "${TPARM_INCLUDES}#include <ncurses/curses.h>\n")
else()
set(TPARM_INCLUDES "${TPARM_INCLUDES}#include <curses.h>\n")
endif()
IF(HAVE_TERM_H)
SET(TPARM_INCLUDES "${TPARM_INCLUDES}#include <term.h>\n")
ELSEIF(HAVE_NCURSES_TERM_H)
SET(TPARM_INCLUDES "${TPARM_INCLUDES}#include <ncurses/term.h>\n")
ENDIF()
if(HAVE_TERM_H)
set(TPARM_INCLUDES "${TPARM_INCLUDES}#include <term.h>\n")
elseif(HAVE_NCURSES_TERM_H)
set(TPARM_INCLUDES "${TPARM_INCLUDES}#include <ncurses/term.h>\n")
endif()
CMAKE_PUSH_CHECK_STATE()
LIST(APPEND CMAKE_REQUIRED_LIBRARIES ${CURSES_LIBRARY})
CHECK_CXX_SOURCE_COMPILES("
# Solaris and X/Open-conforming systems have a fixed-args tparm
cmake_push_check_state()
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CURSES_LIBRARY})
check_cxx_source_compiles("
#define TPARM_VARARGS
${TPARM_INCLUDES}
int main () {
@@ -158,35 +159,24 @@ int main () {
"
TPARM_TAKES_VARARGS
)
IF(NOT TPARM_TAKES_VARARGS)
CHECK_CXX_SOURCE_COMPILES("
${TPARM_INCLUDES}
#define TPARM_VARARGS
int main () {
tparm( \"\" );
}
"
TPARM_TAKES_VARARGS_WITH_VARARGS
)
IF(NOT TPARM_TAKES_VARARGS)
SET(TPARM_SOLARIS_KLUDGE 1)
ELSE()
SET(TPARM_VARARGS 1)
ENDIF()
ENDIF()
CMAKE_POP_CHECK_STATE()
if(TPARM_TAKES_VARARGS)
set(TPARM_VARARGS 1)
else()
set(TPARM_SOLARIS_KLUDGE 1)
endif()
cmake_pop_check_state()
# Work around the fact that cmake does not propagate the language standard flag into
# the CHECK_CXX_SOURCE_COMPILES function. See CMake issue #16456.
# Ensure we do this after the FIND_PACKAGE calls which use C, and will error on a C++
# standards flag.
# Also see https://github.com/fish-shell/fish-shell/issues/5865
IF(NOT POLICY CMP0067)
LIST(APPEND CMAKE_REQUIRED_FLAGS "${CMAKE_CXX${CMAKE_CXX_STANDARD}_EXTENSION_COMPILE_OPTION}")
ENDIF()
if(NOT POLICY CMP0067)
list(APPEND CMAKE_REQUIRED_FLAGS "${CMAKE_CXX${CMAKE_CXX_STANDARD}_EXTENSION_COMPILE_OPTION}")
endif()
CHECK_CXX_SOURCE_COMPILES("
check_cxx_source_compiles("
#include <memory>
int main () {
@@ -196,9 +186,17 @@ int main () {
HAVE_STD__MAKE_UNIQUE
)
FIND_PROGRAM(SED sed)
# Detect support for thread_local.
check_cxx_source_compiles("
int main () {
static thread_local int x = 3;
(void)x;
}
"
HAVE_CX11_THREAD_LOCAL
)
CHECK_CXX_SOURCE_COMPILES("
check_cxx_source_compiles("
#include <atomic>
#include <cstdint>
std::atomic<uint64_t> x;
@@ -207,5 +205,5 @@ int main() {
}"
LIBATOMIC_NOT_NEEDED)
IF (NOT LIBATOMIC_NOT_NEEDED)
SET(ATOMIC_LIBRARY "atomic")
ENDIF()
set(ATOMIC_LIBRARY "atomic")
endif()

View File

@@ -1,21 +1,21 @@
FIND_PROGRAM(SPHINX_EXECUTABLE NAMES sphinx-build
find_program(SPHINX_EXECUTABLE NAMES sphinx-build
HINTS
$ENV{SPHINX_DIR}
PATH_SUFFIXES bin
DOC "Sphinx documentation generator")
INCLUDE(FeatureSummary)
include(FeatureSummary)
SET(SPHINX_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/sphinx_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")
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")
# sphinx-docs uses fish_indent for highlighting.
# Prepend the output dir of fish_indent to PATH.
ADD_CUSTOM_TARGET(sphinx-docs
add_custom_target(sphinx-docs
mkdir -p ${SPHINX_HTML_DIR}/_static/
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/
@@ -26,11 +26,11 @@ ADD_CUSTOM_TARGET(sphinx-docs
-d "${SPHINX_CACHE_DIR}"
"${SPHINX_SRC_DIR}"
"${SPHINX_HTML_DIR}"
DEPENDS sphinx_doc_src/fish_indent_lexer.py fish_indent
DEPENDS ${SPHINX_SRC_DIR}/fish_indent_lexer.py fish_indent
COMMENT "Building HTML documentation with Sphinx")
# sphinx-manpages needs the fish_indent binary for the version number
ADD_CUSTOM_TARGET(sphinx-manpages
add_custom_target(sphinx-manpages
env PATH="$<TARGET_FILE_DIR:fish_indent>:$$PATH"
${SPHINX_EXECUTABLE}
-q -b man
@@ -42,46 +42,46 @@ ADD_CUSTOM_TARGET(sphinx-manpages
DEPENDS fish_indent
COMMENT "Building man pages with Sphinx")
IF(SPHINX_EXECUTABLE)
OPTION(BUILD_DOCS "build documentation (requires Sphinx)" ON)
ELSE(SPHINX_EXECUTABLE)
OPTION(BUILD_DOCS "build documentation (requires Sphinx)" OFF)
ENDIF(SPHINX_EXECUTABLE)
if(SPHINX_EXECUTABLE)
option(BUILD_DOCS "build documentation (requires Sphinx)" ON)
else(SPHINX_EXECUTABLE)
option(BUILD_DOCS "build documentation (requires Sphinx)" OFF)
endif(SPHINX_EXECUTABLE)
IF(BUILD_DOCS AND NOT SPHINX_EXECUTABLE)
MESSAGE(FATAL_ERROR "build documentation selected, but sphinx-build could not be found")
ENDIF()
if(BUILD_DOCS AND NOT SPHINX_EXECUTABLE)
message(FATAL_ERROR "build documentation selected, but sphinx-build could not be found")
endif()
IF(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/user_doc/html
if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/user_doc/html
AND IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/user_doc/man)
SET(HAVE_PREBUILT_DOCS TRUE)
ELSE()
SET(HAVE_PREBUILT_DOCS FALSE)
ENDIF()
set(HAVE_PREBUILT_DOCS TRUE)
else()
set(HAVE_PREBUILT_DOCS FALSE)
endif()
IF(BUILD_DOCS OR HAVE_PREBUILT_DOCS)
SET(INSTALL_DOCS ON)
ELSE()
SET(INSTALL_DOCS OFF)
ENDIF()
if(BUILD_DOCS OR HAVE_PREBUILT_DOCS)
set(INSTALL_DOCS ON)
else()
set(INSTALL_DOCS OFF)
endif()
ADD_FEATURE_INFO(Documentation INSTALL_DOCS "user manual and documentation")
add_feature_info(Documentation INSTALL_DOCS "user manual and documentation")
IF(BUILD_DOCS)
CONFIGURE_FILE("${SPHINX_SRC_DIR}/conf.py" "${SPHINX_BUILD_DIR}/conf.py" @ONLY)
ADD_CUSTOM_TARGET(doc ALL
if(BUILD_DOCS)
configure_file("${SPHINX_SRC_DIR}/conf.py" "${SPHINX_BUILD_DIR}/conf.py" @ONLY)
add_custom_target(doc ALL
DEPENDS sphinx-docs sphinx-manpages)
# Group docs targets into a DocsTargets folder
SET_PROPERTY(TARGET doc sphinx-docs sphinx-manpages
set_property(TARGET doc sphinx-docs sphinx-manpages
PROPERTY FOLDER cmake/DocTargets)
ELSEIF(HAVE_PREBUILT_DOCS)
IF(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
elseif(HAVE_PREBUILT_DOCS)
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
# Out of tree build - link the prebuilt documentation to the build tree
ADD_CUSTOM_TARGET(link_doc ALL)
ADD_CUSTOM_COMMAND(TARGET link_doc
add_custom_target(link_doc ALL)
add_custom_command(TARGET link_doc
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/user_doc ${CMAKE_CURRENT_BINARY_DIR}/user_doc
POST_BUILD)
ENDIF()
ENDIF(BUILD_DOCS)
endif()
endif(BUILD_DOCS)

View File

@@ -5,39 +5,43 @@
# -DBINDIR=L"${CMAKE_INSTALL_FULL_BINDIR}"
# -DDOCDIR=L"${CMAKE_INSTALL_FULL_DOCDIR}")
SET(CMAKE_INSTALL_MESSAGE NEVER)
set(CMAKE_INSTALL_MESSAGE NEVER)
SET(PROGRAMS fish fish_indent fish_key_reader)
set(PROGRAMS fish fish_indent fish_key_reader)
SET(prefix ${CMAKE_INSTALL_PREFIX})
SET(bindir ${CMAKE_INSTALL_BINDIR})
SET(sysconfdir ${CMAKE_INSTALL_SYSCONFDIR})
SET(mandir ${CMAKE_INSTALL_MANDIR})
set(prefix ${CMAKE_INSTALL_PREFIX})
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})
set(rel_datadir ${CMAKE_INSTALL_DATADIR})
set(datadir ${CMAKE_INSTALL_FULL_DATADIR})
SET(docdir ${CMAKE_INSTALL_DOCDIR})
set(docdir ${CMAKE_INSTALL_DOCDIR})
# Comment at the top of some .in files
SET(configure_input
set(configure_input
"This file was generated from a corresponding .in file.\
DO NOT MANUALLY EDIT THIS FILE!")
SET(extra_completionsdir
/usr/local/share/fish/vendor_completions.d
set(rel_completionsdir "fish/vendor_completions.d")
set(rel_functionsdir "fish/vendor_functions.d")
set(rel_confdir "fish/vendor_conf.d")
set(extra_completionsdir
"${datadir}/${rel_completionsdir}"
CACHE STRING "Path for extra completions")
SET(extra_functionsdir
/usr/local/share/fish/vendor_functions.d
set(extra_functionsdir
"${datadir}/${rel_functionsdir}"
CACHE STRING "Path for extra functions")
SET(extra_confdir
/usr/local/share/fish/vendor_conf.d
set(extra_confdir
"${datadir}/${rel_confdir}"
CACHE STRING "Path for extra configuration")
# These are the man pages that go in system manpath; all manpages go in the fish-specific manpath.
SET(MANUALS ${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish.1
set(MANUALS ${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish.1
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish_indent.1
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish_key_reader.1)
@@ -46,54 +50,42 @@ SET(MANUALS ${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish.1
# function on OS X.
# On other operating systems, don't install a realpath man page, as they almost all have a realpath
# command, while macOS does not.
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
SET(CONDEMNED_PAGE "open.1")
ELSE()
SET(CONDEMNED_PAGE "realpath.1")
ENDIF()
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(CONDEMNED_PAGE "open.1")
else()
set(CONDEMNED_PAGE "realpath.1")
endif()
# Define a function to help us create directories.
FUNCTION(FISH_CREATE_DIRS)
FOREACH(dir ${ARGV})
INSTALL(DIRECTORY DESTINATION ${dir})
ENDFOREACH(dir)
ENDFUNCTION(FISH_CREATE_DIRS)
function(FISH_CREATE_DIRS)
foreach(dir ${ARGV})
install(DIRECTORY DESTINATION ${dir})
endforeach(dir)
endfunction(FISH_CREATE_DIRS)
FUNCTION(FISH_TRY_CREATE_DIRS)
FOREACH(dir ${ARGV})
IF(NOT IS_ABSOLUTE ${dir})
SET(abs_dir "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${dir}")
ELSE()
SET(abs_dir "\$ENV{DESTDIR}${dir}")
ENDIF()
INSTALL(SCRIPT CODE "EXECUTE_PROCESS(COMMAND mkdir -p ${abs_dir} OUTPUT_QUIET ERROR_QUIET)
EXECUTE_PROCESS(COMMAND chmod 755 ${abs_dir} OUTPUT_QUIET ERROR_QUIET)
function(FISH_TRY_CREATE_DIRS)
foreach(dir ${ARGV})
if(NOT IS_ABSOLUTE ${dir})
set(abs_dir "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${dir}")
else()
set(abs_dir "\$ENV{DESTDIR}${dir}")
endif()
install(SCRIPT CODE "EXECUTE_PROCESS(COMMAND mkdir -p ${abs_dir} OUTPUT_QUIET ERROR_QUIET)
execute_process(COMMAND chmod 755 ${abs_dir} OUTPUT_QUIET ERROR_QUIET)
")
ENDFOREACH()
ENDFUNCTION(FISH_TRY_CREATE_DIRS)
endforeach()
endfunction(FISH_TRY_CREATE_DIRS)
# $v $(INSTALL) -m 755 -d $(DESTDIR)$(bindir)
# $v for i in $(PROGRAMS); do\
# $(INSTALL) -m 755 $$i $(DESTDIR)$(bindir);\
# echo " Installing $(bo)$$i$(sgr0)";\
# true ;\
# done;
INSTALL(TARGETS ${PROGRAMS}
install(TARGETS ${PROGRAMS}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ
GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
DESTINATION ${bindir})
# $v $(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)/fish
# $v $(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)/fish/conf.d
# $v $(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)/fish/completions
# $v $(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)/fish/functions
# $v $(INSTALL) -m 644 etc/config.fish $(DESTDIR)$(sysconfdir)/fish/
FISH_CREATE_DIRS(${sysconfdir}/fish/conf.d ${sysconfdir}/fish/completions
fish_create_dirs(${sysconfdir}/fish/conf.d ${sysconfdir}/fish/completions
${sysconfdir}/fish/functions)
INSTALL(FILES etc/config.fish DESTINATION ${sysconfdir}/fish/)
install(FILES etc/config.fish DESTINATION ${sysconfdir}/fish/)
FISH_CREATE_DIRS(${rel_datadir}/fish ${rel_datadir}/fish/completions
fish_create_dirs(${rel_datadir}/fish ${rel_datadir}/fish/completions
${rel_datadir}/fish/functions ${rel_datadir}/fish/groff
${rel_datadir}/fish/man/man1 ${rel_datadir}/fish/tools
${rel_datadir}/fish/tools/web_config
@@ -101,77 +93,53 @@ FISH_CREATE_DIRS(${rel_datadir}/fish ${rel_datadir}/fish/completions
${rel_datadir}/fish/tools/web_config/partials
${rel_datadir}/fish/tools/web_config/sample_prompts)
# $v $(INSTALL) -m 644 share/config.fish $(DESTDIR)$(datadir)/fish/
# $v $(INSTALL) -m 644 share/__fish_build_paths.fish $(DESTDIR)$(datadir)/fish/
CONFIGURE_FILE(share/__fish_build_paths.fish.in share/__fish_build_paths.fish)
INSTALL(FILES share/config.fish
configure_file(share/__fish_build_paths.fish.in share/__fish_build_paths.fish)
install(FILES share/config.fish
${CMAKE_CURRENT_BINARY_DIR}/share/__fish_build_paths.fish
DESTINATION ${rel_datadir}/fish)
# $v $(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/pkgconfig
# @echo "Creating placeholder vendor/'extra_' directories"
# -$v $(INSTALL) -m 755 -d $(DESTDIR)$(extra_completionsdir)
# -$v $(INSTALL) -m 755 -d $(DESTDIR)$(extra_functionsdir)
# -$v $(INSTALL) -m 755 -d $(DESTDIR)$(extra_confdir)
# Create only the vendor directories inside the prefix (#5029 / #6508)
FISH_CREATE_DIRS(${rel_datadir}/fish/vendor_completions.d ${rel_datadir}/fish/vendor_functions.d
fish_create_dirs(${rel_datadir}/fish/vendor_completions.d ${rel_datadir}/fish/vendor_functions.d
${rel_datadir}/fish/vendor_conf.d)
# @echo "Installing pkgconfig file"
# $v $(INSTALL) -m 644 fish.pc $(DESTDIR)$(datadir)/pkgconfig
FISH_TRY_CREATE_DIRS(${rel_datadir}/pkgconfig)
CONFIGURE_FILE(fish.pc.in fish.pc.noversion)
fish_try_create_dirs(${rel_datadir}/pkgconfig)
configure_file(fish.pc.in fish.pc.noversion @ONLY)
ADD_CUSTOM_COMMAND(OUTPUT fish.pc
add_custom_command(OUTPUT fish.pc
COMMAND sed '/Version/d' fish.pc.noversion > 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 ${CMAKE_CURRENT_BINARY_DIR}/${FBVF} ${CMAKE_CURRENT_BINARY_DIR}/fish.pc.noversion)
ADD_CUSTOM_TARGET(build_fish_pc ALL DEPENDS fish.pc)
add_custom_target(build_fish_pc ALL DEPENDS fish.pc)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/fish.pc
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fish.pc
DESTINATION ${rel_datadir}/pkgconfig)
# @echo "Installing the $(bo)fish completion library$(sgr0)...";
# $v $(INSTALL) -m 644 $(COMPLETIONS_DIR_FILES:%='%') $(DESTDIR)$(datadir)/fish/completions/
INSTALL(DIRECTORY share/completions/
install(DIRECTORY share/completions/
DESTINATION ${rel_datadir}/fish/completions
FILES_MATCHING PATTERN "*.fish")
# @echo "Installing $(bo)fish functions$(sgr0)";
# $v $(INSTALL) -m 644 $(FUNCTIONS_DIR_FILES:%='%') $(DESTDIR)$(datadir)/fish/functions/
INSTALL(DIRECTORY share/functions/
install(DIRECTORY share/functions/
DESTINATION ${rel_datadir}/fish/functions
FILES_MATCHING PATTERN "*.fish")
# @echo "Installing $(bo)man pages$(sgr0)";
# $v $(INSTALL) -m 644 share/groff/* $(DESTDIR)$(datadir)/fish/groff/
INSTALL(DIRECTORY share/groff
install(DIRECTORY share/groff
DESTINATION ${rel_datadir}/fish)
# $v test -z "$(wildcard share/man/man1/*.1)" || $(INSTALL) -m 644 $(filter-out $(addprefix share/man/man1/, $(CONDEMNED_PAGES)), $(wildcard share/man/man1/*.1)) $(DESTDIR)$(datadir)/fish/man/man1/
# CONDEMNED_PAGE is managed by the conditional above
# Building the man pages is optional: if sphinx isn't installed, they're not built
INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/
DESTINATION ${rel_datadir}/fish/man/man1
FILES_MATCHING
PATTERN "*.1"
PATTERN ${CONDEMNED_PAGE} EXCLUDE)
# @echo "Installing helper tools";
# $v $(INSTALL) -m 755 share/tools/*.py $(DESTDIR)$(datadir)/fish/tools/
INSTALL(PROGRAMS share/tools/create_manpage_completions.py share/tools/deroff.py
install(PROGRAMS share/tools/create_manpage_completions.py share/tools/deroff.py
DESTINATION ${rel_datadir}/fish/tools/)
# $v $(INSTALL) -m 644 share/tools/web_config/*.* $(DESTDIR)$(datadir)/fish/tools/web_config/
# $v $(INSTALL) -m 644 share/tools/web_config/js/*.* $(DESTDIR)$(datadir)/fish/tools/web_config/js/
# $v $(INSTALL) -m 644 share/tools/web_config/partials/* $(DESTDIR)$(datadir)/fish/tools/web_config/partials/
# $v $(INSTALL) -m 644 share/tools/web_config/sample_prompts/*.fish $(DESTDIR)$(datadir)/fish/tools/web_config/sample_prompts/
# $v $(INSTALL) -m 755 share/tools/web_config/*.py $(DESTDIR)$(datadir)/fish/tools/web_config/
INSTALL(DIRECTORY share/tools/web_config
install(DIRECTORY share/tools/web_config
DESTINATION ${rel_datadir}/fish/tools/
FILES_MATCHING
PATTERN "*.png"
@@ -181,52 +149,35 @@ INSTALL(DIRECTORY share/tools/web_config
PATTERN "*.js"
PATTERN "*.fish")
# @echo "Installing more man pages";
# $v $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1;
# $v for i in $(MANUALS); do \
# $(INSTALL) -m 644 $$i $(DESTDIR)$(mandir)/man1/; \
# true; \
# done;
# Building the man pages is optional: if Sphinx isn't installed, they're not built
INSTALL(FILES ${MANUALS} DESTINATION ${mandir}/man1/ OPTIONAL)
#install-doc: $(user_doc)
# @echo "Installing online user documentation";
# $v $(INSTALL) -m 755 -d $(DESTDIR)$(docdir)
# $v for i in user_doc/html/* CHANGELOG.md; do \
# if test -f $$i; then \
# $(INSTALL) -m 644 $$i $(DESTDIR)$(docdir); \
# fi; \
# done;
# Building the manual is optional
INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/user_doc/html/ # Trailing slash is important!
install(FILES ${MANUALS} DESTINATION ${mandir}/man1/ OPTIONAL)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/user_doc/html/ # Trailing slash is important!
DESTINATION ${docdir} OPTIONAL)
INSTALL(FILES CHANGELOG.md DESTINATION ${docdir})
install(FILES CHANGELOG.rst DESTINATION ${docdir})
# $v $(INSTALL) -m 644 share/lynx.lss $(DESTDIR)$(datadir)/fish/
INSTALL(FILES share/lynx.lss DESTINATION ${rel_datadir}/fish/)
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
IF(GETTEXT_FOUND)
FOREACH(lang ${languages})
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${lang}.gmo DESTINATION
if(GETTEXT_FOUND)
foreach(lang ${languages})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${lang}.gmo DESTINATION
${CMAKE_INSTALL_LOCALEDIR}/${lang}/LC_MESSAGES/ RENAME fish.mo)
ENDFOREACH()
ENDIF()
endforeach()
endif()
INSTALL(FILES fish.desktop DESTINATION ${rel_datadir}/applications)
INSTALL(FILES fish.png DESTINATION ${rel_datadir}/pixmaps)
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
set_property(TARGET build_fish_pc CHECK-FISH-BUILD-VERSION-FILE
test_fishscript
test_prep tests_buildroot_target
PROPERTY FOLDER cmake/InstallTargets)
# Make a target build_root that installs into the buildroot directory, for testing.
SET(BUILDROOT_DIR ${CMAKE_CURRENT_BINARY_DIR}/buildroot)
ADD_CUSTOM_TARGET(build_root
set(BUILDROOT_DIR ${CMAKE_CURRENT_BINARY_DIR}/buildroot)
add_custom_target(build_root
COMMAND DESTDIR=${BUILDROOT_DIR} ${CMAKE_COMMAND}
--build ${CMAKE_CURRENT_BINARY_DIR} --target install)

36
cmake/Mac.cmake Normal file
View File

@@ -0,0 +1,36 @@
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
# Code signing ID on Mac. A default '-' is ad-hoc codesign.
# If this is falsey, codesigning is disabled.
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")
function(CODESIGN_ON_MAC target)
if((APPLE) AND (MAC_CODESIGN_ID))
execute_process(COMMAND sw_vers "-productVersion" OUTPUT_VARIABLE OSX_VERSION)
if(MAC_INJECT_GET_TASK_ALLOW)
set(ENTITLEMENTS "--entitlements" "${CMAKE_SOURCE_DIR}/osx/fish_debug.entitlements")
else()
set(ENTITLEMENTS "")
endif(MAC_INJECT_GET_TASK_ALLOW)
if(OSX_VERSION VERSION_LESS "10.13.6")
# `-options runtime` is only available in OS X from 10.13.6 and up
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND codesign --force --deep ${ENTITLEMENTS} --sign "${MAC_CODESIGN_ID}" $<TARGET_FILE:${target}>
VERBATIM
)
else()
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND codesign --force --deep --options runtime ${ENTITLEMENTS} --sign "${MAC_CODESIGN_ID}" $<TARGET_FILE:${target}>
VERBATIM
)
endif()
endif()
endfunction(CODESIGN_ON_MAC target)

View File

@@ -1,12 +1,12 @@
# This is Mac-only.
if (NOT APPLE)
RETURN()
return()
endif (NOT APPLE)
# The source tree containing certain macOS resources.
SET(OSX_DIR ${CMAKE_CURRENT_SOURCE_DIR}/osx)
set(OSX_DIR ${CMAKE_CURRENT_SOURCE_DIR}/osx)
SET(RESOURCE_FILES
set(RESOURCE_FILES
${OSX_DIR}/launch_fish.scpt
${OSX_DIR}/fish_term_icon.icns
${CMAKE_CURRENT_SOURCE_DIR}/build_tools/osx_package_scripts/add-shell
@@ -14,7 +14,7 @@ SET(RESOURCE_FILES
)
# Resource files must be present in the source list.
ADD_EXECUTABLE(fish_macapp EXCLUDE_FROM_ALL
add_executable(fish_macapp EXCLUDE_FROM_ALL
${OSX_DIR}/osx_fish_launcher.m
${RESOURCE_FILES}
)
@@ -22,7 +22,7 @@ ADD_EXECUTABLE(fish_macapp EXCLUDE_FROM_ALL
# Compute the version. Note this is done at generation time, not build time,
# so cmake must be re-run after version changes for the app to be updated. But
# generally this will be run by make_pkg.sh which always re-runs cmake.
EXECUTE_PROCESS(
execute_process(
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build_tools/git_version_gen.sh --stdout
COMMAND cut -d- -f1
OUTPUT_VARIABLE FISH_SHORT_VERSION
@@ -31,12 +31,12 @@ EXECUTE_PROCESS(
# Note CMake appends .app, so the real output name will be fish.app.
# This target does not include the 'base' resource.
SET_TARGET_PROPERTIES(fish_macapp PROPERTIES OUTPUT_NAME "fish")
set_target_properties(fish_macapp PROPERTIES OUTPUT_NAME "fish")
FIND_LIBRARY(FOUNDATION_LIB Foundation)
TARGET_LINK_LIBRARIES(fish_macapp ${FOUNDATION_LIB})
find_library(FOUNDATION_LIB Foundation)
target_link_libraries(fish_macapp ${FOUNDATION_LIB})
SET_TARGET_PROPERTIES(fish_macapp PROPERTIES
set_target_properties(fish_macapp PROPERTIES
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_INFO_PLIST ${OSX_DIR}/CMakeMacAppInfo.plist.in
MACOSX_BUNDLE_GUI_IDENTIFIER "com.ridiculousfish.fish-shell"
@@ -47,12 +47,29 @@ SET_TARGET_PROPERTIES(fish_macapp PROPERTIES
# The fish Mac app contains a fish installation inside the package.
# Here is where it gets built.
# Copy into the fish mac app after.
SET(MACAPP_FISH_BUILDROOT ${CMAKE_CURRENT_BINARY_DIR}/macapp_buildroot/base)
set(MACAPP_FISH_BUILDROOT ${CMAKE_CURRENT_BINARY_DIR}/macapp_buildroot/base)
ADD_CUSTOM_COMMAND(TARGET fish_macapp POST_BUILD
add_custom_command(TARGET fish_macapp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${MACAPP_FISH_BUILDROOT}
COMMAND DESTDIR=${MACAPP_FISH_BUILDROOT} ${CMAKE_COMMAND}
--build ${CMAKE_CURRENT_BINARY_DIR} --target install
COMMAND ${CMAKE_COMMAND} -E copy_directory ${MACAPP_FISH_BUILDROOT}/..
$<TARGET_BUNDLE_CONTENT_DIR:fish_macapp>/Resources/
VERBATIM
)
# The entitlements file.
set(MACAPP_ENTITLEMENTS "${CMAKE_SOURCE_DIR}/osx/MacApp.entitlements")
# Target to sign the macapp.
# Note that a POST_BUILD step happens before resources are copied,
# and therefore would be too early.
add_custom_target(signed_fish_macapp
DEPENDS fish_macapp "${MACAPP_ENTITLEMENTS}"
COMMAND codesign --force --deep
--options runtime
--entitlements "${MACAPP_ENTITLEMENTS}"
--sign "${MAC_CODESIGN_ID}"
$<TARGET_BUNDLE_DIR:fish_macapp>
VERBATIM
)

View File

@@ -1,20 +1,43 @@
# PCRE2 needs some settings.
SET(PCRE2_WIDTH ${WCHAR_T_BITS})
SET(PCRE2_BUILD_PCRE2_8 OFF CACHE BOOL "Build 8bit PCRE2 library")
SET(PCRE2_BUILD_PCRE2_${PCRE2_WIDTH} ON CACHE BOOL "Build ${PCRE2_WIDTH}bit PCRE2 library")
SET(PCRE2_SHOW_REPORT OFF CACHE BOOL "Show the final configuration report")
SET(PCRE2_BUILD_PCRE2GREP OFF CACHE BOOL "Build pcre2grep")
set(PCRE2_WIDTH ${WCHAR_T_BITS})
set(PCRE2_BUILD_PCRE2_8 OFF CACHE BOOL "Build 8bit PCRE2 library")
set(PCRE2_BUILD_PCRE2_${PCRE2_WIDTH} ON CACHE BOOL "Build ${PCRE2_WIDTH}bit PCRE2 library")
set(PCRE2_SHOW_REPORT OFF CACHE BOOL "Show the final configuration report")
set(PCRE2_BUILD_TESTS OFF CACHE BOOL "Build tests")
set(PCRE2_BUILD_PCRE2GREP OFF CACHE BOOL "Build pcre2grep")
set(PCRE2_MIN_VERSION 10.21)
SET(PCRE2_MIN_VERSION 10.21)
FIND_LIBRARY(PCRE2_LIB pcre2-${PCRE2_WIDTH})
FIND_PATH(PCRE2_INCLUDE_DIR pcre2.h)
IF (PCRE2_LIB AND PCRE2_INCLUDE_DIR)
MESSAGE(STATUS "Found system PCRE2 library ${PCRE2_INCLUDE_DIR}")
ELSE()
MESSAGE(STATUS "Using bundled PCRE2 library")
ADD_SUBDIRECTORY(pcre2-10.32 EXCLUDE_FROM_ALL)
SET(PCRE2_INCLUDE_DIR ${CMAKE_BINARY_DIR}/pcre2-10.32/)
SET(PCRE2_LIB pcre2-${PCRE2_WIDTH})
endif(PCRE2_LIB AND PCRE2_INCLUDE_DIR)
INCLUDE_DIRECTORIES(${PCRE2_INCLUDE_DIR})
# Look for a system-installed PCRE2.
find_library(SYS_PCRE2_LIB pcre2-${PCRE2_WIDTH})
find_path(SYS_PCRE2_INCLUDE_DIR pcre2.h)
# We can either use the system-installed PCRE or our bundled version.
# This is controlled by the cache variable FISH_USE_SYSTEM_PCRE2.
# Here we compute the default value for that variable.
if ((APPLE) AND (MAC_CODESIGN_ID))
# On Mac, a codesigned fish will refuse to load a non-codesigned PCRE2
# (e.g. from Homebrew) so default to bundled PCRE2.
set(USE_SYS_PCRE2_DEFAULT OFF)
elseif((NOT SYS_PCRE2_LIB) OR (NOT SYS_PCRE2_INCLUDE_DIR))
# We did not find system PCRE2, so default to bundled.
set(USE_SYS_PCRE2_DEFAULT OFF)
else()
# Default to using the system PCRE2, which was found.
set(USE_SYS_PCRE2_DEFAULT ON)
endif()
set(FISH_USE_SYSTEM_PCRE2 ${USE_SYS_PCRE2_DEFAULT} CACHE BOOL
"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()
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})
endif(FISH_USE_SYSTEM_PCRE2)
include_directories(${PCRE2_INCLUDE_DIR})

View File

@@ -1,38 +1,41 @@
# Define fish_tests.
ADD_EXECUTABLE(fish_tests EXCLUDE_FROM_ALL
add_executable(fish_tests EXCLUDE_FROM_ALL
src/fish_tests.cpp)
FISH_LINK_DEPS(fish_tests)
fish_link_deps_and_sign(fish_tests)
# The "test" directory.
SET(TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/test)
set(TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/test)
# The directory into which fish is installed.
SET(TEST_INSTALL_DIR ${TEST_DIR}/buildroot)
set(TEST_INSTALL_DIR ${TEST_DIR}/buildroot)
# The directory where the tests expect to find the fish root (./bin, etc)
SET(TEST_ROOT_DIR ${TEST_DIR}/root)
set(TEST_ROOT_DIR ${TEST_DIR}/root)
# Copy tests files.
FILE(GLOB TESTS_FILES tests/*)
ADD_CUSTOM_TARGET(tests_dir DEPENDS tests)
file(GLOB TESTS_FILES tests/*)
add_custom_target(tests_dir DEPENDS tests)
IF(NOT FISH_IN_TREE_BUILD)
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)
ENDIF()
add_dependencies(fish_tests tests_dir)
endif()
# Copy littlecheck.py
CONFIGURE_FILE(build_tools/littlecheck.py littlecheck.py COPYONLY)
configure_file(build_tools/littlecheck.py littlecheck.py COPYONLY)
# Copy pexpect_helper.py
configure_file(build_tools/pexpect_helper.py pexpect_helper.py COPYONLY)
# 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
add_custom_target(tests_buildroot_target
COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_INSTALL_DIR}
COMMAND DESTDIR=${TEST_INSTALL_DIR} ${CMAKE_COMMAND}
--build ${CMAKE_CURRENT_BINARY_DIR} --target install
@@ -43,20 +46,20 @@ ADD_CUSTOM_TARGET(tests_buildroot_target
${TEST_ROOT_DIR}
DEPENDS fish fish_test_helper)
IF(NOT FISH_IN_TREE_BUILD)
if(NOT FISH_IN_TREE_BUILD)
# We need to symlink share/functions for the tests.
# This should be simplified.
ADD_CUSTOM_TARGET(symlink_functions
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()
ADD_CUSTOM_TARGET(symlink_functions)
ENDIF()
add_dependencies(tests_buildroot_target symlink_functions)
else()
add_custom_target(symlink_functions)
endif()
# Prep the environment for running the unit tests.
ADD_CUSTOM_TARGET(test_prep
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
@@ -69,46 +72,46 @@ ADD_CUSTOM_TARGET(test_prep
# 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
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}
DEPENDS fish_tests
USES_TERMINAL)
ADD_CUSTOM_TARGET(${TESTTYPE}_fishscript
add_custom_target(${TESTTYPE}_fishscript
COMMAND cd tests && ${TEST_ROOT_DIR}/bin/fish test.fish
DEPENDS test_prep
USES_TERMINAL)
ADD_CUSTOM_TARGET(${TESTTYPE}_interactive
add_custom_target(${TESTTYPE}_interactive
COMMAND cd tests && ${TEST_ROOT_DIR}/bin/fish interactive.fish
DEPENDS test_prep
USES_TERMINAL)
ENDFOREACH(TESTTYPE)
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_dependencies(serial_test_fishscript serial_test_low_level)
add_dependencies(serial_test_interactive serial_test_fishscript)
ADD_CUSTOM_TARGET(serial_test_high_level
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)
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)
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
set_property(TARGET test tests_dir
test_low_level
test_fishscript
test_interactive

View File

@@ -31,25 +31,25 @@
# stays the same (incremental builds must be fast).
# Just a handy abbreviation.
SET(FBVF FISH-BUILD-VERSION-FILE)
set(FBVF FISH-BUILD-VERSION-FILE)
# TODO: find a cleaner way to do this.
IF (${CMAKE_GENERATOR} STREQUAL Ninja)
SET(FBVF-OUTPUT fish-build-version-witness.txt)
SET(CFBVF-BYPRODUCTS ${FBVF})
ELSE(${CMAKE_GENERATOR} STREQUAL Ninja)
SET(FBVF-OUTPUT ${FBVF})
SET(CFBVF-BYPRODUCTS)
ENDIF(${CMAKE_GENERATOR} STREQUAL Ninja)
set(FBVF-OUTPUT fish-build-version-witness.txt)
set(CFBVF-BYPRODUCTS ${FBVF})
else(${CMAKE_GENERATOR} STREQUAL Ninja)
set(FBVF-OUTPUT ${FBVF})
set(CFBVF-BYPRODUCTS)
endif(${CMAKE_GENERATOR} STREQUAL Ninja)
# Set up the version targets
ADD_CUSTOM_TARGET(CHECK-FISH-BUILD-VERSION-FILE
add_custom_target(CHECK-FISH-BUILD-VERSION-FILE
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build_tools/git_version_gen.sh ${CMAKE_CURRENT_BINARY_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
BYPRODUCTS ${CFBVF-BYPRODUCTS})
ADD_CUSTOM_COMMAND(OUTPUT ${FBVF-OUTPUT}
add_custom_command(OUTPUT ${FBVF-OUTPUT}
DEPENDS CHECK-FISH-BUILD-VERSION-FILE)
# Abbreviation for the target.
SET(CFBVF CHECK-FISH-BUILD-VERSION-FILE)
set(CFBVF CHECK-FISH-BUILD-VERSION-FILE)

View File

@@ -1,36 +1,36 @@
SET(languages de en fr nb nn pl pt_BR sv zh_CN)
set(languages de en fr nb nn pl pt_BR sv zh_CN)
INCLUDE(FeatureSummary)
include(FeatureSummary)
OPTION(WITH_GETTEXT "translate messages if gettext is available" ON)
IF(WITH_GETTEXT)
FIND_PACKAGE(Intl)
FIND_PACKAGE(Gettext)
IF(GETTEXT_FOUND)
SET(HAVE_GETTEXT 1)
INCLUDE_DIRECTORIES(${Intl_INCLUDE_DIR})
ENDIF()
ENDIF()
ADD_FEATURE_INFO(gettext GETTEXT_FOUND "translate messages with gettext")
option(WITH_GETTEXT "translate messages if gettext is available" ON)
if(WITH_GETTEXT)
find_package(Intl QUIET)
find_package(Gettext)
if(GETTEXT_FOUND)
set(HAVE_GETTEXT 1)
include_directories(${Intl_INCLUDE_DIR})
endif()
endif()
add_feature_info(gettext GETTEXT_FOUND "translate messages with gettext")
# Define translations
IF(GETTEXT_FOUND)
FOREACH(lang ${languages})
if(GETTEXT_FOUND)
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
gettext_process_po_files(${lang} ALL
PO_FILES po/${lang}.po)
ENDFOREACH()
ENDIF()
endforeach()
endif()
CMAKE_PUSH_CHECK_STATE()
SET(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${Intl_INCLUDE_DIR})
SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${Intl_LIBRARIES})
cmake_push_check_state()
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${Intl_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${Intl_LIBRARIES})
# libintl.h can be compiled into the stdlib on some GLibC systems
IF(Intl_FOUND AND Intl_LIBRARIES)
SET(LIBINTL_INCLUDE "#include <libintl.h>")
ENDIF()
CHECK_CXX_SOURCE_COMPILES("
if(Intl_FOUND AND Intl_LIBRARIES)
set(LIBINTL_INCLUDE "#include <libintl.h>")
endif()
check_cxx_source_compiles("
${LIBINTL_INCLUDE}
#include <stdlib.h>
int main () {
@@ -40,4 +40,4 @@ int main () {
}
"
HAVE__NL_MSG_CAT_CNTR)
CMAKE_POP_CHECK_STATE()
cmake_pop_check_state()

View File

@@ -10,6 +10,9 @@
/* Define to 1 if you have the `ctermid_r' function. */
#cmakedefine HAVE_CTERMID_R 1
/* Define to 1 if C++11 thread_local is supported. */
#cmakedefine HAVE_CX11_THREAD_LOCAL 1
/* Define to 1 if you have the `dirfd' function. */
#cmakedefine HAVE_DIRFD 1
@@ -145,6 +148,9 @@
/* Define to the full name of this package. */
#define PACKAGE_NAME "fish"
/* Use a variadic tparm on NetBSD curses. */
#cmakedefine TPARM_VARARGS 1
/* Define to 1 if tparm accepts a fixed amount of parameters. */
#cmakedefine TPARM_SOLARIS_KLUDGE 1

5
debian/control vendored
View File

@@ -3,7 +3,7 @@ Section: shells
Priority: optional
Maintainer: ridiculous_fish <corydoras@ridiculousfish.com>
Uploaders: David Adam <zanchey@ucc.gu.uwa.edu.au>
Build-Depends: debhelper (>= 9.0.0), libncurses5-dev, cmake3 (>= 3.2.0) | cmake (>= 3.2.0), gettext,
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.
@@ -23,8 +23,9 @@ Description: friendly interactive shell
Package: fish-common
Architecture: all
Multi-Arch: foreign
Depends: ${misc:Depends}
Recommends: fish, python3 (>= 3.5)
Recommends: fish, python3 (>= 3.5), python3-distutils
Suggests: xdg-utils
Replaces: fish (<= 2.1.1.dfsg-2)
Description: friendly interactive shell (architecture-independent files)

View File

@@ -1 +1 @@
README.md
README.rst

4
debian/rules vendored
View File

@@ -7,9 +7,9 @@ export DH_VERBOSE=1
%:
dh $@
# Setting the build system is still required, because otherwise the GNUmakefile gets picked up
override_dh_auto_configure:
# Until all platforms have debhelper 9.20151004, Debian bug 719148 needs to be worked around
dh_auto_configure --buildsystem=cmake --parallel -- -DCMAKE_INSTALL_SYSCONFDIR=/etc
dh_auto_configure --buildsystem=cmake --parallel
override_dh_installdocs:
dh_installdocs --link-doc=fish

4
doc_src/CHANGELOG.rst Normal file
View File

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

View File

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

View File

@@ -79,3 +79,6 @@
.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 }

38
doc_src/cmds/_.rst Normal file
View File

@@ -0,0 +1,38 @@
.. _cmd-_:
_ - call fish's translations
============================
Synopsis
--------
::
_ STRING...
Description
-----------
``_`` translates its arguments into the current language, if possible.
It is equivalent to ``gettext fish STRING``, meaning it can only be used to look up fish's own translations.
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 ``$LANG`` and ``$LC_MESSAGES``.
Options
-------
``_`` has no options.
Examples
--------
::
> _ File
Datei

View File

@@ -9,7 +9,7 @@ Synopsis
::
abbr --add [SCOPE] WORD EXPANSION
abbr --erase word
abbr --erase WORD
abbr --rename [SCOPE] OLD_WORD NEW_WORD
abbr --show
abbr --list
@@ -27,7 +27,7 @@ Options
The following options are available:
- ``-a WORD EXPANSION`` or ``--add WORD EXPANSION`` Adds a new abbreviation, causing WORD to be expanded to PHRASE.
- ``-a WORD EXPANSION`` or ``--add WORD EXPANSION`` Adds a new abbreviation, causing WORD to be expanded to EXPANSION.
- ``-r OLD_WORD NEW_WORD`` or ``--rename OLD_WORD NEW_WORD`` Renames an abbreviation, from OLD_WORD to NEW_WORD.
@@ -39,7 +39,7 @@ The following options are available:
- ``-q`` or ``--query`` Return 0 (true) if one of the WORDs is an abbreviation.
In addition, when adding abbreviations:
In addition, when adding or renaming abbreviations:
- ``-g`` or ``--global`` to use a global variable.
- ``-U`` or ``--universal`` to use a universal variable (default).

View File

@@ -10,7 +10,6 @@ Synopsis
COMMAND1; and COMMAND2
Description
-----------
@@ -25,10 +24,11 @@ Example
The following code runs the ``make`` command to build a program. If the build succeeds, ``make``'s exit status is 0, and the program is installed. If either step fails, the exit status is 1, and ``make clean`` is run, which removes the files created by the build process.
::
make; and make install; or make clean
See Also
--------
- :ref:`or <cmd-or>` command

View File

@@ -103,6 +103,31 @@ See the :ref:`fish_opt <cmd-fish_opt>` command for a friendlier but more verbose
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 you can only call::
cmd --flag=value
# or
cmd -fvalue
but not::
cmd --flag value
# "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
This isn't specific to argparse but common to all things using ``getopt(3)`` (if they have optional arguments at all).
Flag Value Validation
---------------------
@@ -114,7 +139,7 @@ Sometimes you need to validate the option values. For example, that it is a vali
- ``_flag_value`` will be set to the value associated with the flag being processed.
If you do this via a function it should be defined with the ``--no-scope-shadowing`` flag. Otherwise it won't have access to those variables.
These variables are passed to the function as local exported variables.
The script should write any error messages to stdout, not stderr. It should return a status of zero if the flag value is valid otherwise a non-zero status to indicate it is invalid.
@@ -135,7 +160,7 @@ Some OPTION_SPEC examples:
- ``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 can can be used more than once. If it is seen then ``_flag_x`` will be set to the count of how many times the flag was seen.
- ``x`` means that only ``-x`` is valid. It is a boolean that can be used more than once. If it is seen then ``_flag_x`` will be set to the count of how many times the flag was seen.
- ``x=``, ``x=?``, and ``x=+`` are similar to the n/name examples above but there is no long flag alternative to the short flag ``-x``.

View File

@@ -18,13 +18,15 @@ Synopsis
Description
-----------
``bind`` adds a binding for the specified key sequence to the specified command.
``bind`` manages bindings.
SEQUENCE is the character sequence to bind to. These should be written as :ref:`fish escape sequences <escapes>`. For example, because pressing the Alt key and another character sends that character prefixed with an escape character, Alt-based key bindings can be written using the ``\e`` escape. For example, :kbd:`Alt+w` can be written as ``\ew``. The control character can be written in much the same way using the ``\c`` escape, for example :kbd:`Control+X` (^X) can be written as ``\cx``. Note that Alt-based key bindings are case sensitive and Control-based key bindings are not. This is a constraint of text-based terminals, not ``fish``.
It can add bindings if given a SEQUENCE of characters to bind to. These should be written as :ref:`fish escape sequences <escapes>`. The most important of these are ``\c`` for the control key, and ``\e`` for escape, and because of historical reasons also the Alt key (sometimes also called "Meta").
The default key binding can be set by specifying a ``SEQUENCE`` of the empty string (that is, ``''`` ). It will be used whenever no other binding matches. For most key bindings, it makes sense to use the ``self-insert`` function (i.e. ``bind '' self-insert``) as the default keybinding. This will insert any keystrokes not specifically bound to into the editor. Non- printable characters are ignored by the editor, so this will not result in control sequences being printable.
For example, :kbd:`Alt`\ +\ :kbd:`W` can be written as ``\ew``, and :kbd:`Control`\ +\ :kbd:`X` (^X) can be written as ``\cx``. Note that Alt-based key bindings are case sensitive and Control-based key bindings are not. This is a constraint of text-based terminals, not ``fish``.
If the ``-k`` switch is used, the name of the 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.) If used in conjunction with the ``-s`` switch, ``bind`` will silently ignore bindings to named keys that are not found in termcap for the current ``$TERMINAL``, otherwise a warning is emitted.
The generic key binding that matches if no other binding does can be set by specifying a ``SEQUENCE`` of the empty string (that is, ``''`` ). For most key bindings, it makes sense to bind this to the ``self-insert`` function (i.e. ``bind '' self-insert``). This will insert any keystrokes not specifically bound to into the editor. Non-printable characters are ignored by the editor, so this will not result in control sequences being inserted.
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.
``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.
@@ -32,15 +34,17 @@ When ``COMMAND`` is a shellscript command, it is a good practice to put the actu
If a script produces output, it should finish by calling ``commandline -f repaint`` to tell fish that a repaint is in order.
When multiple ``COMMAND``\s are provided, they are all run in the specified order when the key is pressed. 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).
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 specified ``MODE``) are printed. If ``SEQUENCE`` is provided without ``COMMAND``, just the binding matching that sequence is printed.
If no ``SEQUENCE`` is provided, all bindings (or just the bindings in the given ``MODE``) are printed. If ``SEQUENCE`` is provided but no ``COMMAND``, just the binding matching that sequence is printed.
To save custom keybindings, put the ``bind`` statements into :ref:`config.fish <initialization>`. Alternatively, fish also automatically executes a function called ``fish_user_key_bindings`` if it exists.
Key bindings may use "modes", which mimics Vi's modal input behavior. The default mode is "default", and every bind applies to a single mode. The mode can be viewed/changed with the ``$fish_bind_mode`` variable.
The following parameters are available:
Options
-------
The following options are available:
- ``-k`` or ``--key`` Specify a key name, such as 'left' or 'backspace' instead of a character sequence
@@ -58,7 +62,7 @@ The following parameters are available:
- ``-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. ``--preset`` should only be used in full binding sets (like when working on ``fish_vi_key_bindings``).
- ``--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
-----------------------
@@ -120,6 +124,8 @@ The following special input functions are available:
- ``execute`` run the current commandline
- ``force-repaint`` reexecute the prompt functions without coalescing
- ``forward-bigword``, move one whitespace-delimited word to the right
- ``forward-char``, move one character to the right
@@ -158,9 +164,11 @@ The following special input functions are available:
- ``repaint`` reexecutes the prompt functions and redraws the prompt. Multiple successive repaints are coalesced.
- ``repaint-mode`` reexecutes the fish_mode_prompt function and redraws the prompt. This is useful for vi-mode. If no fish_mode_prompt exists, it acts like a normal repaint.
- ``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.
- ``force-repaint`` reexecute the prompt functions without coalescing.
- ``self-insert``, inserts the matching sequence into the command line
- ``self-insert-notfirst``, inserts the matching sequence into the command line, unless the cursor is at the beginning
- ``suppress-autosuggestion``, remove the current autosuggestion
@@ -183,13 +191,11 @@ The following special input functions are available:
Examples
--------
::
bind \cd 'exit'
Causes ``fish`` to exit when :kbd:`Control+D` is pressed.
Causes ``fish`` to exit when :kbd:`Control`\ +\ :kbd:`D` is pressed.
@@ -206,15 +212,34 @@ 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 force-repaint
Turns on Vi key bindings and rebinds :kbd:`Control+C` to clear the input line.
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
--------------------
Unix terminals, like the ones fish operates in, are at heart 70s technology. They have some limitations that applications running inside them can't workaround.
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`).
- 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.
.. _cmd-bind-escape:
Special Case: The escape Character
Special Case: The Escape Character
----------------------------------
The escape key can be used standalone, for example, to switch from insertion mode to normal mode when using Vi keybindings. Escape may also be used as a "meta" key, to indicate the start of an escape sequence, such as function or arrow keys. Custom bindings can also be defined that begin with an escape character.
The escape key can be used standalone, for example, to switch from insertion mode to normal mode when using Vi keybindings. Escape can also be used as a "meta" key, to indicate the start of an escape sequence, like for function or arrow keys. Custom bindings can also be defined that begin with an escape character.
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 300 milliseconds (0.3 seconds) in the default key bindings and 10 milliseconds in the vi key bindings. It can be configured by setting the ``fish_escape_delay_ms`` variable to a value between 10 and 5000 ms. It is recommended that this be a universal variable that you set once from an interactive session.
Holding alt and something else also typically sends escape, for example holding alt+a will send an escape character and then an "a".
Note: fish 2.2.0 and earlier used a default of 10 milliseconds, and provided no way to configure it. That effectively made it impossible to use escape as a meta key.
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.

View File

@@ -23,8 +23,6 @@ Example
-------
The following code searches all .c files for "smurf", and halts at the first occurrence.
::
for i in *.c
@@ -34,3 +32,7 @@ The following code searches all .c files for "smurf", and halts at the first occ
end
end
See Also
--------
- the :ref:`continue <cmd-continue>` command, to skip the remainder of the current iteration of the current inner loop

View File

@@ -1,6 +1,6 @@
.. _cmd-breakpoint:
breakpoint - Launch debug mode
breakpoint - launch debug mode
==============================
Synopsis

View File

@@ -27,8 +27,6 @@ As a special case, ``cd .`` is equivalent to ``cd $PWD``, which is useful in cas
Examples
--------
::
cd
@@ -37,8 +35,7 @@ Examples
cd /usr/src/fish-shell
# changes the working directory to /usr/src/fish-shell
See Also
--------
See also the :ref:`cdh <cmd-cdh>` command for changing to a recently visited directory.
Navigate directories using the :ref:`directory history <directory-history>` or the :ref:`directory stack <directory-stack>`

25
doc_src/cmds/cdh.rst Normal file
View File

@@ -0,0 +1,25 @@
.. _cmd-cdh:
cdh - change to a recently visited directory
============================================
Synopsis
--------
::
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``.
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 :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

View File

@@ -37,9 +37,9 @@ The following options change what part of the commandline is printed or updated:
- ``-b`` or ``--current-buffer`` select the entire buffer, including any displayed autosuggestion (default)
- ``-j`` or ``--current-job`` select the current job
- ``-j`` or ``--current-job`` select the current job - a `job` here is one pipeline. It stops at logical operators or terminators (`;`, `&` or newlines).
- ``-p`` or ``--current-process`` select the current process
- ``-p`` or ``--current-process`` select the current process - a `process` here is one simple command. It stops at logical operators, terminators or pipes.
- ``-s`` or ``--current-selection`` selects the current selection
@@ -72,12 +72,18 @@ If the commandline contains
::
>_ echo $fl___ounder >&2 | less; and echo $catfish
>_ echo $flounder >&2 | less; and echo $catfish
(with the cursor on the "o" of "flounder")
Then the following invocations behave like this:
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.
`$flounder` is the current token.
More examples:
::

View File

@@ -76,13 +76,13 @@ the fish manual.
- ``-u`` and ``--unauthoritative`` no longer do anything and are silently ignored.
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:
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``').
- 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``').
- 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').
- 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.
@@ -111,7 +111,7 @@ The short style option ``-o`` for the ``gcc`` command requires that a file follo
complete -c gcc -s o -r
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:
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:

View File

@@ -20,8 +20,6 @@ Example
The following code removes all tmp files that do not contain the word smurf.
::
for i in *.tmp
@@ -34,3 +32,7 @@ The following code removes all tmp files that do not contain the word smurf.
echo $i
end
See Also
--------
- the :ref:`break <cmd-break>` command, to stop the current inner loop

27
doc_src/cmds/dirh.rst Normal file
View File

@@ -0,0 +1,27 @@
.. _cmd-dirh:
dirh - print directory history
==============================
Synopsis
--------
::
dirh
Description
-----------
``dirh`` prints the current :ref:`directory history <directory-history>`. The current position in the history is highlighted using the color defined in the ``fish_color_history_current`` environment variable.
``dirh`` does not accept any parameters.
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 :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

26
doc_src/cmds/dirs.rst Normal file
View File

@@ -0,0 +1,26 @@
.. _cmd-dirs:
dirs - print directory stack
============================
Synopsis
--------
::
dirs
dirs -c
Description
-----------
``dirs`` prints the current :ref:`directory stack <directory-stack>`, as created by :ref:`pushd <cmd-pushd>` and modified by :ref:`popd <cmd-popd>`.
With "-c", it clears the directory stack instead.
``dirs`` does not accept any parameters.
See Also
--------
- the :ref:`cdh <cmd-cdh>` command which provides a more intuitive way to navigate to recently visited directories.

View File

@@ -19,7 +19,7 @@ Jobs in the list of jobs are sent a hang-up signal when fish terminates, which u
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 ``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.

View File

@@ -57,18 +57,19 @@ If ``-e`` is used, the following sequences are recognized:
Example
-------
::
echo 'Hello World'
Print hello world to stdout
::
echo -e 'Top\\nBottom'
Print Top and Bottom on separate lines, using an escape sequence
See Also
--------
- the :ref:`printf <cmd-printf>` command, for more control over output formatting

View File

@@ -1,6 +1,6 @@
.. _cmd-emit:
emit - Emit a generic event
emit - emit a generic event
===========================
Synopsis

View File

@@ -1,7 +1,7 @@
.. _cmd-end:
end - end a block of commands.
==============================
end - end a block of commands
=============================
Synopsis
--------
@@ -9,17 +9,20 @@ Synopsis
::
begin; [COMMANDS...] end
function NAME [OPTIONS]; COMMANDS...; end
if CONDITION; COMMANDS_TRUE...; [else; COMMANDS_FALSE...;] end
switch VALUE; [case [WILDCARD...]; [COMMANDS...]; ...] end
while CONDITION; COMMANDS...; end
for VARNAME in [VALUES...]; COMMANDS...; end
switch VALUE; [case [WILDCARD...]; [COMMANDS...]; ...] end
Description
-----------
``end`` ends a block of commands.
``end`` ends a block of commands started by one of the following commands:
For more information, read the
documentation for the block constructs, such as ``if``, ``for`` and ``while``.
- :ref:`begin <cmd-begin>` to start a block of commands
- :ref:`function <cmd-function>` to define a function
- :ref:`if <cmd-if>`, :ref:`switch <cmd-switch>` to conditionally execute commands
- :ref:`while <cmd-while>`, :ref:`for <cmd-for>` to perform commands multiple times
The ``end`` command does not change the current exit status. Instead, the status after it will be the status returned by the most recent command.

View File

@@ -15,7 +15,7 @@ Description
-----------
``eval`` evaluates the specified parameters as a command. If more than one parameter is specified, all parameters will be joined using a space character as a separator.
If your command does not need access to stdin, consider using ``source`` instead.
If your command does not need access to stdin, consider using :ref:`source <cmd-source>` instead.
If no piping or other compound shell constructs are required, variable-expansion-as-command, as in ``set cmd ls -la; $cmd``, is also an option.

View File

@@ -14,3 +14,9 @@ Description
-----------
``false`` sets the exit status to 1.
See Also
--------
- :ref:`true <cmd-true>` command
- :ref:`$status <variables-status>` variable

65
doc_src/cmds/fish.rst Normal file
View File

@@ -0,0 +1,65 @@
.. _cmd-fish:
fish - the friendly interactive shell
=====================================
Synopsis
--------
::
fish [OPTIONS] [-c command] [FILE [ARGUMENTS...]]
Description
-----------
fish is a command-line shell written mainly with interactive use in mind. This page briefly describes the options for invoking fish. The :ref:`full manual <intro>` is available in HTML by using the :ref:`help <cmd-help>` command from inside fish, and in the `fish-doc(1)` man page. The :ref:`tutorial <tutorial>` is available as HTML via ``help tutorial`` or in `fish-tutorial(1)`.
The following options are available:
- ``-c`` or ``--command=COMMANDS`` evaluate the specified commands instead of reading from the commandline
- ``-C`` or ``--init-command=COMMANDS`` evaluate the specified commands after reading the configuration, before running the command specified by ``-c`` or reading interactive input
- ``-d`` or ``--debug=DEBUG_CATEGORIES`` enable debug output and specify a pattern for matching debug categories. See :ref:`Debugging <debugging-fish>` below for details.
- ``-o`` or ``--debug-output=DEBUG_FILE`` specify a file path to receive the debug output, including categories and ``fish_trace``. The default is stderr.
- ``-i`` or ``--interactive`` specify that fish is to run in interactive mode
- ``-l`` or ``--login`` specify that fish is to run as a login shell
- ``-n`` or ``--no-execute`` do not execute any commands, only perform syntax checking
- ``-p`` or ``--profile=PROFILE_FILE`` when fish exits, output timing information on all executed commands to the specified file
- ``-P`` or ``--private`` enables :ref:`private mode <private-mode>`, so fish will not access old or store new history.
- ``--print-rusage-self`` when fish exits, output stats from getrusage
- ``--print-debug-categories`` outputs the list of debug categories, and then exits.
- ``-v`` or ``--version`` display version and exit
- ``-D`` or ``--debug-stack-frames=DEBUG_LEVEL`` specify how many stack frames to display when debug messages are written. The default is zero. A value of 3 or 4 is usually sufficient to gain insight into how a given debug call was reached but you can specify a value up to 128.
- ``-f`` or ``--features=FEATURES`` enables one or more :ref:`feature flags <featureflags>` (separated by a comma). These are how fish stages changes that might break scripts.
The fish exit status is generally the :ref:`exit status of the last foreground command <variables-status>`.
.. _debugging-fish:
Debugging
---------
While fish provides extensive support for :ref:`debugging fish scripts <debugging>`, it is also possible to debug and instrument its internals. Debugging can be enabled by passing the ``--debug`` option. For example, the following command turns on debugging for background IO thread events, in addition to the default categories, i.e. *debug*, *error*, *warning*, and *warning-path*::
> fish --debug=iothread
Available categories are listed by ``fish --print-debug-categories``. The ``--debug`` option accepts a comma-separated list of categories, and supports glob syntax. The following command turns on debugging for *complete*, *history*, *history-file*, and *profile-history*, as well as the default categories::
> fish --debug='complete,*history*'
Debug messages output to stderr by default. Note that if ``fish_trace`` is set, execution tracing also outputs to stderr by default. You can output to a file using the ``--debug-output`` option::
> fish --debug='complete,*history*' --debug-output=/tmp/fish.log --init-command='set fish_trace on'

View File

@@ -0,0 +1,66 @@
.. _cmd-fish_add_path:
fish_add_path - add to the path
==============================================================
Synopsis
--------
::
fish_add_path [paths...]
fish_add_path (-h | --help)
fish_add_path [(-g | --global) | (-U | --universal) | (-P | --path)] [(-m | --move)] [(-a | --append) | (-p | --prepend)] [(-v | --verbose) | (-n | --dry-run)] [paths...]
Description
-----------
``fish_add_path`` is a simple way to add more components to fish's $PATH. It does this by adding the components either to $fish_user_paths or directly to $PATH (if the ``--path`` switch is given).
It is (by default) safe to use ``fish_add_path`` in config.fish, or it can be used once, interactively, and the paths will stay in future because of :ref:`universal variables <variables-universal>`. This is a "do what I mean" style command, if you need more control, consider modifying the variable yourself.
Components are normalized by :ref:`realpath <cmd-realpath>`. This means that trailing slashes are ignored and symlinks are resolved, and relative paths are made absolute. If a component already exists, it is not added again and stays in the same place unless the ``--move`` switch is given.
Components are added in the order they are given, and they are prepended to the path unless ``--append`` is given (if $fish_user_paths is used, that means they are last in $fish_user_paths, which is itself prepended to $PATH, so they still stay ahead of the system paths).
If no component is new, the variable ($fish_user_paths or $PATH) is not set again or otherwise modified, so variable handlers are not triggered.
If a component is not an existing directory, ``fish_add_path`` ignores it.
Options
-------
- ``-a`` or ``--append`` causes the components to be added to the *end* of the variable
- ``-p`` or ``--prepend`` causes the components to be added to the *front* of the variable (this is the default)
- ``-g`` or ``--global`` means to use a global $fish_user_paths
- ``-U`` or ``--universal`` means to use a universal $fish_user_paths - this is the default if it doesn't already exist
- ``-P`` or ``--path`` means to use $PATH directly
- ``-m`` or ``--move`` means to move already existing components to the place they would be added - by default they would be left in place and not added again
- ``-v`` or ``--verbose`` means to print the :ref:`set <cmd-set>` command used
- ``-n`` or ``--dry-run`` means to print the ``set`` command that would be used without executing it
If ``--move`` is used, it may of course lead to the path swapping order, so you should be careful doing that in config.fish.
Example
-------
::
# I just installed mycoolthing and need to add it to the path to use it.
fish_add_path /opt/mycoolthing/bin
# I want my ~/.local/bin to be checked first.
fish_add_path -m ~/.local/bin
# I prefer using a global fish_user_paths
fish_add_path -g ~/.local/bin ~/.otherbin /usr/local/sbin
# I want to append to the entire $PATH because this directory contains fallbacks
fish_add_path -aP /opt/fallback/bin
# I want to add the bin/ directory of my current $PWD (say /home/nemo/)
> fish_add_path -v bin/
set fish_user_paths /home/nemo/bin /usr/bin /home/nemo/.local/bin

View File

@@ -19,7 +19,11 @@ The fish_hg_prompt function displays information about the current Mercurial rep
`Mercurial <https://www.mercurial-scm.org/>`_ (``hg``) must be installed.
There are numerous customization options, which can be controlled with fish variables.
By default, only the current branch is shown because ``hg status`` can take be slow on large repository. You can enable a more informative prompt by setting the variable ``$fish_prompt_hg_show_informative_status``, for example::
set --universal fish_prompt_hg_show_informative_status
If you enabled the informative status, there are numerous customization options, which can be controlled with fish variables.
- ``$fish_color_hg_clean``, ``$fish_color_hg_modified`` and ``$fish_color_hg_dirty`` are colors used when the repository has the respective status.
@@ -52,6 +56,7 @@ A simple prompt that displays hg info::
function fish_prompt
...
set -g fish_prompt_hg_show_informative_status
printf '%s %s$' $PWD (fish_hg_prompt)
end

View File

@@ -28,7 +28,7 @@ The following options are available:
- ``--html`` outputs HTML, which supports syntax highlighting if the appropriate CSS is defined. The CSS class names are the same as the variable names, such as ``fish_color_command``.
- ``-d`` or ``--debug=CATEGORY_GLOB`` enables debug output and specifies a glob for matching debug categories (like ``fish -d``). Defaults to empty.
- ``-d`` or ``--debug-level=DEBUG_LEVEL`` enables debug output and specifies a verbosity level. Defaults to 0.
- ``-D`` or ``--debug-stack-frames=DEBUG_LEVEL`` specify how many stack frames to display when debug messages are written. The default is zero. A value of 3 or 4 is usually sufficient to gain insight into how a given debug call was reached but you can specify a value up to 128.

View File

@@ -15,16 +15,12 @@ Description
``fish_key_reader`` is used to study input received from the terminal and can help with key binds. The program is interactive and works on standard input. Individual characters themselves and their hexadecimal values are displayed.
The tool will write an example ``bind`` command matching the character sequence captured to stdout. If the character sequence matches a special key name (see ``bind --key-names``), both ``bind CHARS ...`` and ``bind -k KEYNAME ...`` usage will be shown. Additional details about the characters received, such as the delay between chars, are written to stderr.
The tool will write an example :ref:`bind <cmd-bind>` command matching the character sequence captured to stdout. If the character sequence matches a special key name (see ``bind --key-names``), both ``bind CHARS ...`` and ``bind -k KEYNAME ...`` usage will be shown. Additional details about the characters received, such as the delay between chars, are written to stderr.
The following options are available:
- ``-c`` or ``--continuous`` begins a session where multiple key sequences can be inspected. By default the program exits after capturing a single key sequence.
- ``-d`` or ``--debug=CATEGORY_GLOB`` enables debug output and specifies a glob for matching debug categories (like ``fish -d``). Defaults to empty.
- ``-D`` or ``--debug-stack-frames=DEBUG_LEVEL`` specify how many stack frames to display when debug messages are written. The default is zero. A value of 3 or 4 is usually sufficient to gain insight into how a given debug call was reached but you can specify a value up to 128.
- ``-h`` or ``--help`` prints usage information.
- ``-v`` or ``--version`` prints fish_key_reader's version and exits.
@@ -36,7 +32,7 @@ The delay in milliseconds since the previous character was received is included
``fish_key_reader`` intentionally disables handling of many signals. To terminate ``fish_key_reader`` in ``--continuous`` mode do:
- press ``Ctrl-C`` twice, or
- press ``Ctrl-D`` twice, or
- press :kbd:`Control`\ +\ :kbd:`C` twice, or
- press :kbd:`Control`\ +\ :kbd:`D` twice, or
- type ``exit``, or
- type ``quit``

View File

@@ -18,10 +18,14 @@ Description
The ``fish_mode_prompt`` function outputs the mode indicator for use in vi-mode.
The default ``fish_mode_prompt`` function will output indicators about the current Vi editor mode displayed to the left of the regular prompt. Define your own function to customize the appearance of the mode indicator. You can also define an empty ``fish_mode_prompt`` function to remove the Vi mode indicators. The ``$fish_bind_mode variable`` can be used to determine the current mode. It
will be one of ``default``, ``insert``, ``replace_one``, or ``visual``.
The default ``fish_mode_prompt`` function will output indicators about the current Vi editor mode displayed to the left of the regular prompt. Define your own function to customize the appearance of the mode indicator. The ``$fish_bind_mode variable`` can be used to determine the current mode. It will be one of ``default``, ``insert``, ``replace_one``, or ``visual``.
fish_mode_prompt will be executed when the vi mode changes. If it produces any output, it is displayed and used. If it does not, the other prompt functions (:ref:`fish_prompt <cmd-fish_prompt>` and :ref:`fish_right_prompt <cmd-fish_right_prompt>`) will be executed as well in case they contain a mode display.
You can also define an empty ``fish_mode_prompt`` function to remove the Vi mode indicators::
function fish_mode_prompt; end
funcsave fish_mode_prompt
``fish_mode_prompt`` will be executed when the vi mode changes. If it produces any output, it is displayed and used. If it does not, the other prompt functions (:ref:`fish_prompt <cmd-fish_prompt>` and :ref:`fish_right_prompt <cmd-fish_right_prompt>`) will be executed as well in case they contain a mode display.
Example
-------

View File

@@ -1,6 +1,6 @@
.. _cmd-fish_update_completions:
fish_update_completions - Update completions using manual pages
fish_update_completions - update completions using manual pages
===============================================================
Synopsis

View File

@@ -25,6 +25,8 @@ It calls out to VCS-specific functions. The currently supported systems are:
If a VCS isn't installed, the respective function does nothing.
The svn prompt is disabled by default because it's slow on large svn repositories. To enable it, modify fish_vcs_prompt to uncomment it. See :ref:`funced <cmd-funced>`.
For more information, see the documentation for each of the functions above.
Example

View File

@@ -1,7 +1,7 @@
.. _cmd-for:
for - perform a set of commands multiple times.
===============================================
for - perform a set of commands multiple times
==============================================
Synopsis
--------

View File

@@ -15,7 +15,7 @@ Description
``funced`` provides an interface to edit the definition of the function ``NAME``.
If the ``$VISUAL`` environment variable is set, it will be used as the program to edit the function. If ``$VISUAL`` is unset but ``$EDITOR`` is set, that will be used. Otherwise, a built-in editor will be used. Note that to enter a literal newline using the built-in editor you should press :kbd:`Alt+Enter`. Pressing :kbd:`Enter` signals that you are done editing the function. This does not apply to an external editor like emacs or vim.
If the ``$VISUAL`` environment variable is set, it will be used as the program to edit the function. If ``$VISUAL`` is unset but ``$EDITOR`` is set, that will be used. Otherwise, a built-in editor will be used. Note that to enter a literal newline using the built-in editor you should press :kbd:`Alt`\ +\ :kbd:`Enter`. Pressing :kbd:`Enter` signals that you are done editing the function. This does not apply to an external editor like emacs or vim.
If there is no function called ``NAME`` a new function will be created with the specified name
@@ -24,3 +24,20 @@ If there is no function called ``NAME`` a new function will be created with the
- ``-i`` or ``--interactive`` Force opening the function body in the built-in editor even if ``$VISUAL`` or ``$EDITOR`` is defined.
- ``-s`` or ``--save`` Automatically save the function after successfully editing it.
Example
-------
Say you want to modify your prompt.
Run::
>_ funced fish_prompt
This will open up your editor, allowing you to modify the function. When you're done, save and quit. Fish will reload the function, so you should see the changes right away.
When you're done, use::
>_ funcsave fish_prompt
For more, see :ref:`funcsave <cmd-funcsave>`.

View File

@@ -9,11 +9,14 @@ Synopsis
::
funcsave FUNCTION_NAME
funcsave [(-d | --directory) where/to/save ] FUNCTION_NAME
Description
-----------
``funcsave`` saves the current definition of a function to a file in the fish configuration directory. This function will be automatically loaded by current and future fish sessions. This can be useful if you have interactively created a new function and wish to save it for later use.
``funcsave`` saves a function to a file in the fish configuration directory. This function will be automatically loaded by current and future fish sessions. This can be useful if you have interactively created a new function and wish to save it for later use.
Note that because fish loads functions on-demand, saved functions will not function as :ref:`event handlers <event>` until they are run or sourced otherwise. To activate an event handler for every new shell, add the function to your :ref:`shell initialization file <initialization>` instead of using ``funcsave``.
This is typically used together with :ref:`funced <cmd-funced>`, which will open the function in your editor and load it in the current seession afterwards.

View File

@@ -39,7 +39,7 @@ The following options are available:
- ``-s`` or ``--on-signal SIGSPEC`` tells fish to run this function when the signal SIGSPEC is delivered. SIGSPEC can be a signal number, or the signal name, such as SIGHUP (or just HUP).
- ``-S`` or ``--no-scope-shadowing`` allows the function to access the variables of calling functions. Normally, any variables inside the function that have the same name as variables from the calling function are "shadowed", and their contents is independent of the calling function.
- ``-S`` or ``--no-scope-shadowing`` allows the function to access the variables of calling functions. Normally, any variables inside the function that have the same name as variables from the calling function are "shadowed", and their contents are independent of the calling function.
It's important to note that this does not capture referenced variables or the scope at the time of function declaration! At this time, fish does not have any concept of closures, and variable lifetimes are never extended. In other words, by using ``--no-scope-shadowing`` the scope of the function each time it is run is shared with the scope it was *called* from rather than the scope it was *defined* in.
- ``-V`` or ``--inherit-variable NAME`` snapshots the value of the variable ``NAME`` and defines a local variable with that same name and value when the function is defined. This is similar to a closure in other languages like Python but a bit different. Note the word "snapshot" in the first sentence. If you change the value of the variable after defining the function, even if you do so in the same scope (typically another function) the new value will not be used by the function you just created using this option. See the ``function notify`` example below for how this might be used.
@@ -52,13 +52,11 @@ By using one of the event handler switches, a function can be made to run automa
- ``fish_command_not_found``, which is emitted whenever a command lookup failed.
- ``fish_preexec``, which is emitted right before executing an interactive command. The commandline is passed as the first parameter.
- ``fish_preexec``, which is emitted right before executing an interactive command. The commandline is passed as the first parameter. Not emitted if command is empty.
Note: This event will be emitted even if the command is invalid. The commandline parameter includes the entire commandline verbatim, and may potentially include newlines.
- ``fish_posterror``, which is emitted right after executing a command with syntax errors. The commandline is passed as the first parameter.
- ``fish_postexec``, which is emitted right after executing an interactive command. The commandline is passed as the first parameter.
Note: This event will be emitted even if the command is invalid. The commandline parameter includes the entire commandline verbatim, and may potentially include newlines.
- ``fish_postexec``, which is emitted right after executing an interactive command. The commandline is passed as the first parameter. Not emitted if command is empty.
- ``fish_exit`` is emitted right before fish exits.

View File

@@ -29,7 +29,7 @@ The following options are available:
- ``-e`` or ``--erase`` causes the specified functions to be erased. This also means that it is prevented from autoloading.
- ``-D`` or ``--details`` reports the path name where the specified function is defined or could be autoloaded, ``stdin`` if the function was defined interactively or on the command line or by reading stdin, ``-`` if the function was created via ``source``, and ``n/a`` if the function isn't available. (Functions created via ``alias`` will return ``-``, because ``alias`` uses ``source`` internally.) If the ``--verbose`` option is also specified then five lines are written:
- ``-D`` or ``--details`` reports the path name where the specified function is defined or could be autoloaded, ``stdin`` if the function was defined interactively or on the command line or by reading stdin, ``-`` if the function was created via :ref:`source <cmd-source>`, and ``n/a`` if the function isn't available. (Functions created via :ref:`alias <cmd-alias>` will return ``-``, because ``alias`` uses ``source`` internally.) If the ``--verbose`` option is also specified then five lines are written:
- the pathname as already described,
- ``autoloaded``, ``not-autoloaded`` or ``n/a``,

View File

@@ -27,4 +27,4 @@ Note that most builtin commands display their help in the terminal when given th
Example
-------
``help fg`` shows the documentation for the ``fg`` builtin.
``help fg`` shows the documentation for the :ref:`fg <cmd-fg>` builtin.

View File

@@ -1,6 +1,6 @@
.. _cmd-history:
history - Show and manipulate command history
history - show and manipulate command history
=============================================
Synopsis

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