Compare commits

..

49 Commits

Author SHA1 Message Date
Johannes Altmanninger
03cee61f77 Atom feed of PRs adding/removing translations to/from po/*.po
(This is experimental, and our concrete need to automate this is not
super high, but I want to have a solution for this problem in general.)

There are various automated ways to notify people of changes to a
component, without them having to set up complicated filtering.
For example
1. using GitHub's codeowners feature, perhaps creating a GitHub team
   per component
2. by requiring all changes to the component to go through a fork
3. Using [public-inbox](https://public-inbox.org/)'s "lei" tool,
   which makes it easy to create a filter for all patches touching a given file
   (consumable as pull-based mbox or RSS feed), see
   https://people.kernel.org/monsieuricon/lore-lei-part-1-getting-started

Option 3 seems ideal because it allows anyone to subscribe/unsubscribe,
and it remains obvious where to send PRs to.

It would be fairly easy to write a client-side tool (fetch all commits
and/or PRs and look for interesting changes) but people are more likely
to use something that works OOTB with newsreaders / mail clients.

Expose atom feeds of PRs proposing translation additions/removals.
The one with removals is higher traffic because it can be triggered
when rewording a source string.

Feeds are already online. For example, use:

	https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/zh_CN-additions.atom
	https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/zh_CN-removals.atom

Ref: https://github.com/fish-shell/fish-shell/pull/11833#discussion_r2394161766
2025-10-03 10:26:56 +02:00
Johannes Altmanninger
db6a7d26cd update_translations.sh: add header to new files too
Fixes #11855
2025-10-01 18:30:38 +02:00
Johannes Altmanninger
6be03d7cc4 update_translations.sh: fix test invocation when passed a file in non-extant directory
Need to make sure test arguments are not empty lists.
2025-10-01 18:30:38 +02:00
Daniel Rainer
617a6edb13 Extract messages without building default features
Default features are not needed for message extraction, so there is no
need to spend any resources on them.

If a PO files contains a syntax error, extraction would fail if the
`localize-messages` feature is active. This is undesirable, because it
results in an unnecessary failure with worse error messages than if the
`msgmerge` invocation of the `update_translations.fish` script fails.

Closes #11849
2025-10-01 08:05:37 +02:00
王宇逸
31c85723e8 zh_CN: don't translate set command
Closes #11852
2025-10-01 08:02:38 +02:00
王宇逸
d22c905d9f zh_CN: fix typo
Part of #11852
2025-10-01 08:02:38 +02:00
Daniel Rainer
216dc2d473 Remove redundant variable declaration
Closes #11851
2025-10-01 08:00:21 +02:00
Daniel Rainer
918e7abe6b Hide output of msgfmt -h
This command is only used to determine availability of `msgfmt`. Without
these changes, the entire help output shows up if the code panics later
on, which adds useless bloat to the output, making it harder to analyze
what went wrong.

Closes #11848
2025-10-01 07:59:46 +02:00
Daniel Rainer
c145ee6df3 Check exit status of msgfmt
Prior to this, when `msgfmt` failed, this would be detected indirectly
by the parser, which would then panic due to it input being empty.

Explicit checking allows us to properly display `msgfmt`'s error
message.

Closes #11847
2025-10-01 07:59:21 +02:00
Johannes Altmanninger
62543b36a4 release.sh: sunset release announcement email
I'm not sure if our peer projects do this or if it's useful to have
on top of github releases (especially as most releases are patch
releases mainly).

We could certainly use "sphinx-build -b text" in
build_tools/release-notes.sh to extract a nice plaintext changelog
and send that, but that doesn't support links.  Not sure about HTML
email either.
2025-10-01 07:26:50 +02:00
Daniel Rainer
751aad5302 Refactor PO section marking
Use msgids to mark sections. In the PO format, comments are associated
with specific messages, which does not match the semantics for section
markers.
Furthermore, comments are not preserved by `msgmerge`, which required
quite convoluted handling to copy them over from the template.
By using msgids to mark sections, this problem is avoided.

This convoluted handling was also used for header comments. Header
comments are now handled in a simpler way. There is a fixed prefix,
identifying these comments, as well as a list variable containing the
lines which should be put into the header. When a PO file is generated,
all existing lines starting with the prefix are deleted, the and the
current version of the lines is prepended to the file.

Closes #11845
2025-09-30 19:45:31 +02:00
Daniel Rainer
efabab492a Remove useless comments
Most of them have been added automatically for no good reason.

Also remove outdated comments referring to source locations in pt_BR.po.

Closes #11844
2025-09-30 19:44:36 +02:00
Daniel Rainer
c7cdbe60cd Put general comments on top of empty msgid
These should not be comments on an actual message, since they apply
throughout the entire file, so the sensible location is as comments on
the empty msgid.

Closes #11843
2025-09-30 19:44:15 +02:00
Johannes Altmanninger
412149a5de Changelog update for 4.1.1 2025-09-30 19:22:41 +02:00
Johannes Altmanninger
abd23d2a1b Increase escape sequence timeout while waiting for query response
Running "fish -d reader" inside SSH inside Windows terminal sometimes
results in hangs on startup (or whenever we run "scrollback-push"),
because not all of the Primary DA response is available for reading
at once:

	reader: Incomplete escape sequence: \e\[?61\;4\;6\;7\;14\;21\;22\;23\;24\;28\;32

Work around this by increasing the read timeout while we're waiting
for query responses.

We should try to find a better (more comprehensive?) fix in future,
but for the patch release, this small change will do.

Fixes #11841
2025-09-30 19:00:40 +02:00
Johannes Altmanninger
b774c54a6f Changelog for translation fixes from #11833 2025-09-30 19:00:40 +02:00
王宇逸
e4b797405b zh_CN: fix tier 1 translations
Closes #11833
2025-09-30 18:41:44 +02:00
Johannes Altmanninger
81a89a5dec release-notes.sh: fix sphinx warning for patch release notes
Integration_4.1.1 fails to generate release notes with

	CHANGELOG.rst:9: WARNING: Bullet list ends without a blank
	line; unexpected unindent. [docutils].
2025-09-30 18:00:09 +02:00
Johannes Altmanninger
0da12a6b55 Primary Device Attribute is a proper noun
We don't care about any specific attributes but we do very much care
about the specific query and response format associated with VT100's
primary device attribute query. Use a proper noun to emphasize that
we want that one and no other.

Ref: https://github.com/fish-shell/fish-shell/pull/11833#discussion_r2385659040
2025-09-30 12:06:08 +02:00
Johannes Altmanninger
86ec8994e6 build.rs: fix MSRV (1.70) clippy 2025-09-30 12:06:08 +02:00
Johannes Altmanninger
caf426ddb2 po/de.po: copy-edit German translations
Go through all existing translations except for tier3.
2025-09-30 11:50:43 +02:00
Johannes Altmanninger
508ae410a6 builtin commandline: fix completion description 2025-09-30 11:47:26 +02:00
Johannes Altmanninger
993b977c9b builtin function: remove dead code 2025-09-30 11:47:26 +02:00
Johannes Altmanninger
a7f0138fc7 builtin function: fix a misleading error message
Issue introduced in 7914c92824 (replaced the functions '--rename'
option with '--copy'., 2010-09-09).
2025-09-30 11:47:26 +02:00
Johannes Altmanninger
ab3c932903 builtin set: fix regression in error message description 2025-09-30 11:47:26 +02:00
Johannes Altmanninger
ae0fdadcff Remove translations for some error messages that basically never happen
Executable path is empty only in contrived circumstances.

The regex error happens only when the user explicitly turns off a
feature flag.

The orphaned process error seems very unlikely, not worth translating.
2025-09-30 11:47:26 +02:00
Johannes Altmanninger
e3974989d8 Fix short description for builtin wait 2025-09-30 11:47:26 +02:00
Johannes Altmanninger
080b1e0e4f Translation update implied by parent commit
Part of #11833
2025-09-30 11:47:26 +02:00
Johannes Altmanninger
a5db91dd85 po: add section markers to indicate translation priority
Part of #11833
2025-09-30 11:47:26 +02:00
Johannes Altmanninger
b62f54631b Translation update implied by parent commit
Part of #11833
2025-09-30 11:47:26 +02:00
Johannes Altmanninger
d835c5252a Prepare to not localize private function descriptions
The overwhelming majority of localizable messages comes from
completions:

	$ ls share/completions/ | wc -l
	$ 1048

OTOH functions also contribute a small amount, mostly via their
descriptions (so usually just one per file).

	$ ls share/functions/ | wc -l
	$ 237

Most of these are private and almost never shown to the user, so it's
not worth bothering translators with them. So:

- Skip private (see the parent commit) and deprecated functions.
- Skip wrapper functions like grep (where the translation seems to
  be provided by apropos), and even the English description is not
  helpful.
  - Assume that most real systems have "seq", "realpath" etc.,
    so it's no use providing our own translations for our fallbacks.
- Mark fish's own functions as tier1, and some barely-used functiosn
  and completions as tier3, so we can order them that way in
  po/*.po. Most translators should only look at tier1 and tier2.
  In future we could disable localization for tier3.

See the explanation at the bottom of
tests/checks/message-localization-tier-is-declared.fish

Part of #11833
2025-09-30 11:47:26 +02:00
Johannes Altmanninger
a53db72564 Mark private functions that don't need localization
See the next commit.

Part of #11833
2025-09-30 11:47:26 +02:00
Johannes Altmanninger
61b0368dac functions/realpath: remove weird wrapping
Wrapping the same thing is redundant and wrapping grealpath is kinda
pointless since we only provide completions for realpath.
2025-09-30 11:47:26 +02:00
Integral
568b4a22f9 completions/help: correct the spelling of "redirection"
Closes #11839
2025-09-30 11:47:26 +02:00
Jiangqiu Shen
8abba8a089 Re-add translations for share/completions/cjpm.fish
As removed in the parent commit.
Cherry-picked from e4c55131c7 (Update translation, 2025-07-04)
2025-09-30 11:47:26 +02:00
王宇逸
b3b789cd68 zh_CN: bad translations are worse than none
Part of #11833
2025-09-30 11:47:26 +02:00
Johannes Altmanninger
425a166111 functions/seq: use early return 2025-09-30 10:37:11 +02:00
Johannes Altmanninger
1dcc290e29 tests/checks/check-all-fish-files.fish: follow naming convention 2025-09-30 10:37:11 +02:00
Johannes Altmanninger
863204dbfa build.rs: remove dead code 2025-09-30 10:37:11 +02:00
Sebastian Fleer
4b21e7c9c7 webconfig: Replace str.stripprefix with str.removeprefix
str.stripprefix doesn't exist in Python:
https://docs.python.org/3/library/stdtypes.html#str.removeprefix

Closes #11840
2025-09-30 10:37:06 +02:00
Johannes Altmanninger
df5230ff4a Reliably disable modifyOtherKeys on WezTerm
WezTerm allows applications to enable modifyOtherKeys by default.
Its implementation has issues on non-English or non-QWERTY layouts,
see https://github.com/wezterm/wezterm/issues/6087 and #11204.

fish 4.0.1 disabled modifyOtherKeys on WezTerm specifically
(7ee6d91ba0 (Work around keyboard-layout related bugs in WezTerm's
modifyOtherKeys, 2025-03-03)), fish 4.1.0 didn't, because at that
time, WezTerm would advertise support for the kitty keyboard protocol
(even if applications are not allowed to enable it) which would make
fish skip requesting the legacy modifyOtherKeys.

WezTerm no longer advertises that if config.enable_kitty_keyboard
is false.  Let's work around it in another way.
2025-09-30 10:33:03 +02:00
Johannes Altmanninger
7cd0943056 Tighten some screws for TTY-specific workarounds 2025-09-30 10:25:23 +02:00
Johannes Altmanninger
6f0532460a fish_config: fix for non-embedded builds
I only tested with embedded-builds; CMake tests were failing because
they use different code paths here.

fish_config could use some love.  Start by extracting common
functionality between "{theme,prompt} show", fixing the behavior.

Fixes 29a35a7951 (fish_config: fix "prompt/theme show" in embed-data
builds, 2025-09-28).
2025-09-28 12:29:18 +02:00
Johannes Altmanninger
29a35a7951 fish_config: fix "prompt/theme show" in embed-data builds
Fixes #11832
2025-09-28 10:59:53 +02:00
Johannes Altmanninger
dd0d45f88f fish_config prompt: remove dead code
Commit 2b74affaf0 (Add prompt selector, 2021-04-22)
intentionally added an unused code path that checks for
$__fish_data_dir/sample_prompts, see

https://github.com/fish-shell/fish-shell/pull/7958#discussion_r621320945

> (note: This was added in preparation of moving the sample_prompts directory out of web_config -
> because it no longer is web-exclusive)

Remove it.
2025-09-28 10:11:01 +02:00
Johannes Altmanninger
0ff0de7efe release workflow: install msgfmt for staticbuilds
This makes us actually embed localized messages.

Part of #11828
2025-09-28 09:56:57 +02:00
Johannes Altmanninger
092ef99551 macos CI: explicitly install gettext
We need msgfmt for embedding translations.

Part of #11828
2025-09-28 09:54:30 +02:00
Johannes Altmanninger
97ae05b69d build_tools/release.sh: actually add new docs
Not quite sure for which step this is actually needed.  While at it,
fix the errexit issue that caused this blunder.
2025-09-27 22:56:49 +02:00
Johannes Altmanninger
3d8eca178e start new cycle
Created by ./build_tools/release.sh 4.1.0
2025-09-27 22:41:54 +02:00
38 changed files with 510 additions and 385 deletions

View File

@@ -163,7 +163,7 @@ jobs:
# --break-system-packages because homebrew has now declared itself "externally managed".
# this is CI so we don't actually care.
sudo pip3 install --break-system-packages pexpect
brew install tmux
brew install gettext tmux
- name: cmake
run: |
mkdir build && cd build

View File

@@ -150,6 +150,8 @@ jobs:
uses: ./.github/actions/rust-toolchain@stable
with:
targets: aarch64-apple-darwin
- name: Install dependencies
run: brew install gettext
- name: Build and codesign
run: |
die() { echo >&2 "$*"; exit 1; }

View File

@@ -0,0 +1,56 @@
on:
pull_request_target:
types: [opened, synchronize]
workflow_dispatch:
inputs:
pr_number:
description: Pull request number
required: true
type: number
permissions:
contents: write
jobs:
update-event-feeds:
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: |
sudo apt install python3-git python3-polib
sudo pip3 install --break-system-packages feedgen==1.0.0
- name: Update event feeds
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
set -x
if [ "${{ github.event_name }}" = pull_request ]; then
pr_number=${{ github.event.pull_request.number }}
else
pr_number=${{ inputs.pr_number }}
fi
# E.g. https://github.com/fish-shell/fish-shell
repo_url=${{ github.server_url }}/${{ github.repository }}
workflow_sha=${{ github.workflow_sha }}
run_id=${{ github.run_id }}
events_ref=refs/fish-shell-events
git clone "$repo_url" --revision="$events_ref" worktree --depth=1
cd worktree
git fetch origin "$workflow_sha" --depth=1
set -o pipefail
git show "$workflow_sha":build_tools/event-feeds.py |
python - "$pr_number"
git add .
if git diff --cached --exit-code; then
exit
fi
git config user.name fish-shell-bot
git config user.email fish-shell-bot
git commit -m "update via github run ID $run_id"
cat >>.git/config <<'EOF'
[credential]
username = fish-shell-bot
helper = !sh -c 'echo "password=$GITHUB_TOKEN"'
EOF
# Might fail due to a race; that's usually fine to ignore...
git push origin HEAD:"$events_ref" ||:

View File

@@ -1,22 +1,8 @@
fish 4.1.2 (released October 07, 2025)
======================================
fish ?.?.? (released ???)
=========================
This release fixes the following regressions identified in 4.1.0:
- Fixed spurious error output when completing remote file paths for ``scp`` (:issue:`11860`).
- Fixed the :kbd:`alt-l` binding not formatting ``ls`` output correctly (one entry per line, no colors) (:issue:`11888`).
- Fixed an issue where focus events (currently only enabled in ``tmux``) would cause multiline prompts to be redrawn in the wrong line (:issue:`11870`).
- Stopped printing output that would cause a glitch on old versions of Midnight Commander (:issue:`11869`).
- Added a fix for some configurations of Zellij where :kbd:`escape` key processing was delayed (:issue:`11868`).
- Fixed a case where the :doc:`web-based configuration tool <cmds/fish_config>` would generate invalid configuration (:issue:`11861`).
- Fixed a case where pasting into ``fish -c read`` would fail with a noisy error (:issue:`11836`).
- Fixed a case where upgrading fish would break old versions of fish that were still running.
In general, fish still needs to be restarted after it is upgraded,
except for `standalone builds <https://github.com/fish-shell/fish-shell/?tab=readme-ov-file#building-fish-with-embedded-data-experimental>`__.
fish 4.1.1 (released September 30, 2025)
========================================
fish 4.1.1 (released ???)
=========================
This release fixes the following regressions identified in 4.1.0:

2
Cargo.lock generated
View File

@@ -105,7 +105,7 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "fish"
version = "4.1.2"
version = "4.1.0-snapshot"
dependencies = [
"bitflags",
"cc",

View File

@@ -64,7 +64,7 @@ debug = true
[package]
name = "fish"
version = "4.1.2"
version = "4.1.0-snapshot"
edition.workspace = true
rust-version.workspace = true
default-run = "fish"

View File

@@ -16,7 +16,7 @@ fn main() {
// language server.
rsconf::set_env_value(
"FISH_RESOLVED_BUILD_DIR",
"FISH_BUILD_DIR",
// If set by CMake, this might include symlinks. Since we want to compare this to the
// dir fish is executed in we need to canonicalize it.
canonicalize(fish_build_dir()).to_str().unwrap(),

155
build_tools/event-feeds.py Normal file
View File

@@ -0,0 +1,155 @@
from datetime import datetime
from pathlib import Path
from typing import Tuple
import dateutil.tz
import json
import re
import os
import subprocess
import sys
import xml.etree.ElementTree as ET
# TODO maybe use https://github.com/getpelican/feedgenerator instead?
from feedgen.feed import FeedGenerator
import git
import polib
def message_dictionary(repo, ref, file: Path):
po_contents = repo.git().show(f"{ref}:{file}")
messages = polib.pofile(po_contents)
return {e.msgid: e.msgstr for e in messages}
def write_feed(
feed_path: Path,
base_ref_oid: str,
title: str,
subtitle: str,
this_pr: Tuple[str, str] | None,
):
fg = FeedGenerator()
tree_url = (
"https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events"
)
feed_url = f"{tree_url}/{feed_path}"
fg.id(feed_url)
fg.title(title)
fg.subtitle(subtitle)
fg.link(href=feed_url, rel="self")
generator_url = f"https://github.com/fish-shell/fish-shell/blob/{base_ref_oid}/.github/workflows/update-event-feeds.yml"
fg.link(href=generator_url, rel="alternate")
entries = {}
if feed_path.exists():
tree = ET.parse(feed_path)
root = tree.getroot()
xmlns = "{http://www.w3.org/2005/Atom}"
for child in root.findall(f"{xmlns}entry"):
pr_url = child.find(f"{xmlns}id").text
pr_title = child.find(f"{xmlns}title").text
updated = child.find(f"{xmlns}updated").text
updated = datetime.fromisoformat(updated)
entries[pr_url] = (pr_title, updated)
if this_pr is not None:
(this_pr_title, this_pr_url) = this_pr
if this_pr_url not in entries:
entries[this_pr_url] = (this_pr_title, datetime.now(dateutil.tz.tzutc()))
for pr_url, (pr_title, updated) in entries.items():
fe = fg.add_entry()
fe.id(pr_url)
fe.title(pr_title)
fe.updated(updated)
fe.link(href=pr_url)
atomfeed = fg.atom_str(pretty=True).decode()
feed_path.write_text(atomfeed)
def pull_request_data(pr_number: str):
data = json.loads(
subprocess.check_output(
(
"gh",
"pr",
"view",
"--json",
"baseRefOid,headRefOid,title,url",
str(pr_number),
),
text=True,
)
)
base_ref_oid = data["baseRefOid"]
head_ref_oid = data["headRefOid"]
this_pr_title = data["title"]
this_pr_url = data["url"]
return (base_ref_oid, head_ref_oid, this_pr_title, this_pr_url)
def main():
pr_number = sys.argv[1]
(base_ref_oid, head_ref_oid, this_pr_title, this_pr_url) = pull_request_data(
pr_number
)
repo = git.Repo()
repo.git().execute(("git", "fetch", "origin", base_ref_oid, head_ref_oid))
po_files = (
Path(file)
for file in repo.git()
.execute(("git", "ls-tree", "--name-only", base_ref_oid, ":/po/"))
.splitlines()
)
changed_files = {
Path(file)
for file in subprocess.check_output(
("git", "diff", "--name-only", base_ref_oid, head_ref_oid), text=True
).splitlines()
if re.match(r"^po/\w+\.po$", file)
}
Path("po").mkdir(exist_ok=True)
for po_file in po_files:
file_without_extension = str(po_file).removesuffix(".po")
ll_CC = os.path.basename(file_without_extension)
feed_additions_path = Path(f"{file_without_extension}-additions.atom")
feed_removals_path = Path(f"{file_without_extension}-removals.atom")
def title(verb: str):
return f"fish-shell PRs {verb} {ll_CC} translations"
def write_additions(this_pr):
subtitle = "PRs that add new translations"
write_feed(
feed_additions_path, base_ref_oid, title("adding"), subtitle, this_pr
)
def write_removals(this_pr):
subtitle = "PRs that remove translations, often due to a change in the messages source"
write_feed(
feed_removals_path, base_ref_oid, title("removing"), subtitle, this_pr
)
if not feed_additions_path.exists():
write_additions(None)
if not feed_removals_path.exists():
write_removals(None)
if po_file not in changed_files:
continue
old = message_dictionary(repo, base_ref_oid, po_file)
new = message_dictionary(repo, head_ref_oid, po_file)
if any(
new_msgstr != old.get(new_msgid) and new_msgstr != ""
for (new_msgid, new_msgstr) in new.items()
):
write_additions((this_pr_title, this_pr_url))
elif any(
old_msgstr != "" and new.get(old_msgid, "") == ""
for (old_msgid, old_msgstr) in old.items()
):
write_removals((this_pr_title, this_pr_url))
if __name__ == "__main__":
main()

View File

@@ -27,11 +27,19 @@ begin
else
set rust_extraction_file (mktemp)
# We need to build to ensure that the proc macro for extracting strings runs.
FISH_GETTEXT_EXTRACTION_FILE=$rust_extraction_file cargo check --features=gettext-extract
FISH_GETTEXT_EXTRACTION_FILE=$rust_extraction_file cargo check --no-default-features --features=gettext-extract
or exit 1
end
echo '# fish-section-tier1-from-rust'
function mark_section
set -l section_name $argv[1]
echo 'msgid "fish-section-'$section_name'"'
echo 'msgstr ""'
echo ''
end
mark_section tier1-from-rust
# Get rid of duplicates and sort.
msguniq --no-wrap --strict --sort-output $rust_extraction_file
or exit 1
@@ -77,13 +85,13 @@ begin
# This regex handles explicit requests to translate a message. These are more important to translate
# than messages which should be implicitly translated.
set -l explicit_regex '.*\( *_ (([\'"]).+?(?<!\\\\)\\2) *\).*'
echo "# fish-section-$tier-from-script-explicitly-added"
mark_section "$tier-from-script-explicitly-added"
extract_fish_script_messages_impl $explicit_regex $argv
# This regex handles descriptions for `complete` and `function` statements. These messages are not
# particularly important to translate. Hence the "implicit" label.
set -l implicit_regex '^(?:\s|and |or )*(?:complete|function).*? (?:-d|--description) (([\'"]).+?(?<!\\\\)\\2).*'
echo "# fish-section-$tier-from-script-implicitly-added"
mark_section "$tier-from-script-implicitly-added"
extract_fish_script_messages_impl $implicit_regex $argv
end

View File

@@ -32,7 +32,6 @@ done
repo_root="$(dirname "$0")/.."
fish_site=$repo_root/../fish-site
fish_site_repo=git@github.com:$repository_owner/fish-site
for path in . "$fish_site"
do
@@ -43,13 +42,6 @@ do
fi
done
(
cd "$fish_site"
[ "$(git rev-parse HEAD)" = \
"$(git ls-remote "$fish_site_repo" refs/heads/master |
awk '{print $1}')" ]
)
if git tag | grep -qxF "$version"; then
echo >&2 "$0: tag $version already exists"
exit 1
@@ -155,20 +147,14 @@ rm -rf "$tmpdir"
" | sed 's,^\s*| \?,,')"
)
gh_api_repo() {
path=$1
shift
command gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$repository_owner/fish-shell/$path" \
"$@"
}
# Approve macos-codesign
# TODO what if current user can't approve?
gh_pending_deployments() {
gh_api_repo "actions/runs/$run_id/pending_deployments" "$@"
command gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$repository_owner/fish-shell/actions/runs/$run_id/pending_deployments" \
"$@"
}
while {
environment_id=$(gh_pending_deployments | jq .[].environment.id)
@@ -184,7 +170,7 @@ echo '
"comment": "Approved via ./build_tools/release.sh"
}
' |
gh_pending_deployments --method POST --input=-
gh_pending_deployments -XPOST --input=-
# Await completion.
gh run watch "$run_id"
@@ -212,12 +198,12 @@ done
" | sed 's,^\s*| \?,,')"
# This takes care to support remote names that are different from
# fish-shell remote name. Also, support detached HEAD state.
git push "$fish_site_repo" HEAD:master
git push git@github.com:$repository_owner/fish-site HEAD:master
)
if [ -n "$integration_branch" ]; then {
git push $remote "$version^{commit}":refs/heads/$integration_branch
} else {
else
changelog=$(cat - CHANGELOG.rst <<EOF
fish ?.?.? (released ???)
=========================
@@ -229,25 +215,6 @@ EOF
git push $remote HEAD:master
} fi
milestone_number=$(
gh_api_repo milestones?state=open |
jq '.[] | select(.title == "fish '"$version"'") | .number'
)
gh_api_repo --method PATCH milestones/$milestone_number \
--raw-field state=closed
next_patch_version=$(
echo "$version" | awk -F. '
NF == 3 && $3 ~ /[0-9]+/ {
printf "%s.%s.%s", $1, $2, $3+1
}
'
)
if [ -n "$next_patch_version" ]; then
gh_api_repo --method POST milestones \
--raw-field title="fish $next_patch_version"
fi
exit
}

View File

@@ -31,7 +31,6 @@
set -gx LC_ALL C.UTF-8
set -l build_tools (status dirname)
set -g tmpdir
set -l po_dir $build_tools/../po
set -l extract
@@ -46,8 +45,8 @@ if test -z $argv[1]
else
set -l po_dir_id (stat --format='%d:%i' -- $po_dir)
for arg in $argv
set -l arg_dir_id (stat --format='%d:%i' -- (dirname $arg))
if test $po_dir_id != $arg_dir_id
set -l arg_dir_id (stat --format='%d:%i' -- (dirname $arg) 2>/dev/null)
if test $po_dir_id != "$arg_dir_id"
echo "Argument $arg is not a file in the directory $(realpath $po_dir)."
echo "Non-option arguments must specify paths to files in this directory."
echo ""
@@ -99,44 +98,38 @@ if set -l --query _flag_dry_run
cp -r $po_dir/* $tmpdir
end
# This is used to identify lines which should be set here via $header_lines.
# Make sure that this prefix does not appear elsewhere in the file and only contains characters
# without special meaning in a sed pattern.
set -g header_prefix "# fish-note: "
function print_header -a po_file
set -l ll_CC (basename $po_file .po)
set -l header_lines \
"To subscribe to proposed updates, point your feed reader at:" \
https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/$ll_CC-additions.atom \
https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/$ll_CC-removals.atom \
"Translations are divided into sections, each starting with a fish-section-* pseudo-message." \
"The first few sections are more important." \
"Ignore the tier3 sections unless you have a lot of time."
for line in $header_lines
printf '%s%s\n' $header_prefix $line
end
end
function merge_po_files --argument-names template_file po_file
msgmerge --no-wrap --update --no-fuzzy-matching --backup=none --quiet \
$po_file $template_file
or cleanup_exit
set -l new_po_file (mktemp) # TODO Remove on failure.
# Remove obsolete messages instead of keeping them as #~ entries.
and msgattrib --no-wrap --no-obsolete -o $new_po_file $po_file
or cleanup_exit
begin
echo "# fish-note-sections: Translations are divided into sections, each starting with a fish-section-* comment."
echo "# fish-note-sections: The first few sections are more important."
echo "# fish-note-sections: Ignore the tier3 sections unless you have a lot of time."
sed -i '
/^# fish-note-sections:/d;
/^# fish-section-/d;
' $new_po_file
set -l next_line 1
set -l section
awk <$template_file '
/^# fish-section-\S*$/ {
section = $0
}
section != "" && /^msgid ".+"$/ {
print section
print $0
section = ""
}
' |
while read -l section
read -l msgid_line
set -l line_number (grep -m1 -Fxn $msgid_line $new_po_file | string split :)[1]
sed -n "$next_line,$(math $line_number - 1)"p $new_po_file
echo $section
set next_line $line_number
# set section
end
sed -n "$next_line,\$"p $new_po_file
print_header $po_file
# Paste PO file without old header lines.
sed '/^'$header_prefix'/d' $new_po_file
end >$po_file
rm $new_po_file
end
@@ -149,7 +142,10 @@ for po_file in $po_files
if test -e $po_file
merge_po_files $template_file $po_file
else
cp $template_file $po_file
begin
print_header $po_file
cat $template_file
end >$po_file
end
end
end

View File

@@ -12,7 +12,7 @@ fn cargo_target_dir() -> Cow<'static, Path> {
}
pub fn fish_build_dir() -> Cow<'static, Path> {
// This is set if using CMake.
// FISH_BUILD_DIR is set by CMake, if we are using it.
option_env!("FISH_BUILD_DIR")
.map(|d| Cow::Borrowed(Path::new(d)))
.unwrap_or(cargo_target_dir())

View File

@@ -2,7 +2,7 @@
env,
ffi::OsStr,
path::{Path, PathBuf},
process::Command,
process::{Command, Stdio},
};
fn main() {
@@ -34,7 +34,11 @@ fn embed_localizations(cache_dir: &Path) {
// for the respective language.
let mut catalogs = phf_codegen::Map::new();
match Command::new("msgfmt").arg("-h").status() {
match Command::new("msgfmt")
.arg("-h")
.stdout(Stdio::null())
.status()
{
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
rsconf::warn!(
"Cannot find msgfmt to build gettext message catalogs. Localization will not work."
@@ -97,6 +101,12 @@ fn embed_localizations(cache_dir: &Path) {
.arg(&po_file_path)
.output()
.unwrap();
if !output.status.success() {
panic!(
"msgfmt failed:\n{}",
String::from_utf8(output.stderr).unwrap()
);
}
let mo_data = output.stdout;
// Extract map from MO data.

View File

@@ -1,6 +1,9 @@
# fish-note-sections: Translations are divided into sections, each starting with a fish-section-* comment.
# fish-note-sections: The first few sections are more important.
# fish-note-sections: Ignore the tier3 sections unless you have a lot of time.
# fish-note: To subscribe to proposed updates, point your feed reader at:
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/de-additions.atom
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/de-removals.atom
# fish-note: Translations are divided into sections, each starting with a fish-section-* pseudo-message.
# fish-note: The first few sections are more important.
# fish-note: Ignore the tier3 sections unless you have a lot of time.
# translation of de.po to deutsch
# This file is distributed under the same license as the PACKAGE package.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER.
@@ -21,6 +24,9 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.5\n"
msgid "fish-section-tier1-from-rust"
msgstr ""
msgid ""
"\n"
" PID Command\n"
@@ -29,7 +35,6 @@ msgstr ""
" PID Befehl\n"
#, c-format
# fish-section-tier1-from-rust
msgid " (%ls)\n"
msgstr " (%ls)\n"
@@ -200,7 +205,6 @@ msgstr "%ls: %ls: ungültiger Unterbefehl\n"
msgid "%ls: %ls: invalid variable name. See `help identifiers`\n"
msgstr ""
#
#, c-format
msgid "%ls: %ls: option does not take an argument\n"
msgstr ""
@@ -409,7 +413,6 @@ msgstr ""
msgid "%ls: Invalid --min-args value '%ls'\n"
msgstr ""
#
#, c-format
msgid "%ls: Invalid --unknown-arguments value '%ls'\n"
msgstr ""
@@ -702,7 +705,6 @@ msgstr ""
msgid "%ls: expected a numeric value"
msgstr "%ls: Erwartete numerischen Wert"
#
#, c-format
msgid "%ls: fish was not built with embedded files"
msgstr ""
@@ -799,17 +801,14 @@ msgstr ""
msgid "%s"
msgstr ""
#
#, c-format
msgid "%s %s: unrecognized feature '%ls'"
msgstr ""
#
#, c-format
msgid "%s and %s are mutually exclusive"
msgstr ""
#
#, c-format
msgid "%s could not read response to Primary Device Attribute query after waiting for %d seconds. This is often due to a missing feature in your terminal. See 'help terminal-compatibility' or 'man fish-terminal-compatibility'. This %s process will no longer wait for outstanding queries, which disables some optional features."
msgstr ""
@@ -1117,7 +1116,6 @@ msgstr ""
msgid "Failed to assign shell to its own process group"
msgstr "Konnte Shell nicht einer eigenen Prozessgruppe zuweisen"
#
#, c-format
msgid "Failed to set terminal mode (%s)"
msgstr ""
@@ -1195,7 +1193,6 @@ msgstr "Illegale Instruktion"
msgid "Incomplete escape sequence '%ls'"
msgstr "Unvollständige Escapesequenz '%ls'"
#
msgid "Information request"
msgstr ""
@@ -1522,7 +1519,6 @@ msgstr "Derzeit ausführende Funktion stoppen"
msgid "Stop the innermost loop"
msgstr "Innerste Schleife beenden"
#
msgid "Synchronized file access"
msgstr ""
@@ -1710,7 +1706,6 @@ msgstr "Nicht passender Platzhalter"
msgid "Unsupported use of '='. In fish, please use 'set %ls %ls'."
msgstr ""
#
msgid "Unused signal"
msgstr ""
@@ -1738,7 +1733,6 @@ msgstr ""
msgid "Variables cannot be bracketed. In fish, please use {$%ls}."
msgstr ""
#
msgid "Virtual timer expired"
msgstr ""
@@ -1902,7 +1896,9 @@ msgstr "unbegrenzt\n"
msgid "|& is not valid. In fish, use &| to pipe both stdout and stderr."
msgstr "|& ist ungültig. In fish, nutze &| um stdout und stderr gleichzeitig zu pipen"
# fish-section-tier1-from-script-explicitly-added
msgid "fish-section-tier1-from-script-explicitly-added"
msgstr ""
msgid "%ls: %ls: expected %d arguments; got %d\\n"
msgstr ""
@@ -2125,7 +2121,9 @@ msgstr "oder die Datei war leer"
msgid "python executable not found"
msgstr ""
# fish-section-tier1-from-script-implicitly-added
msgid "fish-section-tier1-from-script-implicitly-added"
msgstr ""
msgid "# comments"
msgstr ""
@@ -3827,7 +3825,12 @@ msgstr ""
msgid "~ expansion"
msgstr ""
# fish-section-tier3-from-script-implicitly-added
msgid "fish-section-tier3-from-script-explicitly-added"
msgstr ""
msgid "fish-section-tier3-from-script-implicitly-added"
msgstr ""
msgid " "
msgstr ""

View File

@@ -1,6 +1,9 @@
# fish-note-sections: Translations are divided into sections, each starting with a fish-section-* comment.
# fish-note-sections: The first few sections are more important.
# fish-note-sections: Ignore the tier3 sections unless you have a lot of time.
# fish-note: To subscribe to proposed updates, point your feed reader at:
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/en-additions.atom
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/en-removals.atom
# fish-note: Translations are divided into sections, each starting with a fish-section-* pseudo-message.
# fish-note: The first few sections are more important.
# fish-note: Ignore the tier3 sections unless you have a lot of time.
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
@@ -21,13 +24,15 @@ msgstr ""
"X-Poedit-Basepath: /home/david/src/fish-shell\n"
"X-Generator: Poedit 1.8.11\n"
msgid "fish-section-tier1-from-rust"
msgstr ""
msgid ""
"\n"
" PID Command\n"
msgstr ""
#, c-format
# fish-section-tier1-from-rust
msgid " (%ls)\n"
msgstr ""
@@ -198,7 +203,6 @@ msgstr ""
msgid "%ls: %ls: invalid variable name. See `help identifiers`\n"
msgstr ""
#
#, c-format
msgid "%ls: %ls: option does not take an argument\n"
msgstr ""
@@ -379,7 +383,6 @@ msgstr "%ls: Expected exactly two names (current function name, and new function
msgid "%ls: Expected generic | variable | signal | exit | job-id for --handlers-type\n"
msgstr ""
#
#, c-format
msgid "%ls: Function '%ls' already exists. Cannot create copy of '%ls'\n"
msgstr ""
@@ -408,7 +411,6 @@ msgstr ""
msgid "%ls: Invalid --min-args value '%ls'\n"
msgstr ""
#
#, c-format
msgid "%ls: Invalid --unknown-arguments value '%ls'\n"
msgstr ""
@@ -701,7 +703,6 @@ msgstr ""
msgid "%ls: expected a numeric value"
msgstr "%ls: expected a numeric value"
#
#, c-format
msgid "%ls: fish was not built with embedded files"
msgstr ""
@@ -798,17 +799,14 @@ msgstr ""
msgid "%s"
msgstr ""
#
#, c-format
msgid "%s %s: unrecognized feature '%ls'"
msgstr ""
#
#, c-format
msgid "%s and %s are mutually exclusive"
msgstr ""
#
#, c-format
msgid "%s could not read response to Primary Device Attribute query after waiting for %d seconds. This is often due to a missing feature in your terminal. See 'help terminal-compatibility' or 'man fish-terminal-compatibility'. This %s process will no longer wait for outstanding queries, which disables some optional features."
msgstr ""
@@ -912,7 +910,6 @@ msgstr "An error occurred while setting up pipe"
msgid "Argument is not a number: '%ls'"
msgstr ""
#
msgid "Await background process completion"
msgstr ""
@@ -1117,7 +1114,6 @@ msgstr ""
msgid "Failed to assign shell to its own process group"
msgstr ""
#
#, c-format
msgid "Failed to set terminal mode (%s)"
msgstr ""
@@ -1521,7 +1517,6 @@ msgstr "Stop the currently evaluated function"
msgid "Stop the innermost loop"
msgstr "Stop the innermost loop"
#
msgid "Synchronized file access"
msgstr ""
@@ -1736,7 +1731,6 @@ msgstr ""
msgid "Variables cannot be bracketed. In fish, please use {$%ls}."
msgstr ""
#
msgid "Virtual timer expired"
msgstr ""
@@ -1900,7 +1894,9 @@ msgstr ""
msgid "|& is not valid. In fish, use &| to pipe both stdout and stderr."
msgstr ""
# fish-section-tier1-from-script-explicitly-added
msgid "fish-section-tier1-from-script-explicitly-added"
msgstr ""
msgid "%ls: %ls: expected %d arguments; got %d\\n"
msgstr ""
@@ -2123,7 +2119,9 @@ msgstr ""
msgid "python executable not found"
msgstr ""
# fish-section-tier1-from-script-implicitly-added
msgid "fish-section-tier1-from-script-implicitly-added"
msgstr ""
msgid "# comments"
msgstr ""
@@ -3825,7 +3823,12 @@ msgstr ""
msgid "~ expansion"
msgstr ""
# fish-section-tier3-from-script-implicitly-added
msgid "fish-section-tier3-from-script-explicitly-added"
msgstr ""
msgid "fish-section-tier3-from-script-implicitly-added"
msgstr ""
msgid " "
msgstr ""

View File

@@ -1,6 +1,9 @@
# fish-note-sections: Translations are divided into sections, each starting with a fish-section-* comment.
# fish-note-sections: The first few sections are more important.
# fish-note-sections: Ignore the tier3 sections unless you have a lot of time.
# fish-note: To subscribe to proposed updates, point your feed reader at:
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/fr-additions.atom
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/fr-removals.atom
# fish-note: Translations are divided into sections, each starting with a fish-section-* pseudo-message.
# fish-note: The first few sections are more important.
# fish-note: Ignore the tier3 sections unless you have a lot of time.
# translation of fr.po to Français
# FRENCH TRANSLATION FOR FISH
# Copyright (C) 2006 Xavier Douville
@@ -120,6 +123,9 @@ msgstr ""
"X-Generator: Gtranslator 2.91.7\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
msgid "fish-section-tier1-from-rust"
msgstr ""
msgid ""
"\n"
" PID Command\n"
@@ -128,7 +134,6 @@ msgstr ""
" PID Commande\n"
#, c-format
# fish-section-tier1-from-rust
msgid " (%ls)\n"
msgstr ""
@@ -299,7 +304,6 @@ msgstr ""
msgid "%ls: %ls: invalid variable name. See `help identifiers`\n"
msgstr ""
#
#, c-format
msgid "%ls: %ls: option does not take an argument\n"
msgstr ""
@@ -480,7 +484,6 @@ msgstr "%ls : Exactement deux noms attendus (noms de fonctions actuel et projet
msgid "%ls: Expected generic | variable | signal | exit | job-id for --handlers-type\n"
msgstr ""
#
#, c-format
msgid "%ls: Function '%ls' already exists. Cannot create copy of '%ls'\n"
msgstr ""
@@ -509,7 +512,6 @@ msgstr "%ls : Valeur --max-args '%ls' invalide\n"
msgid "%ls: Invalid --min-args value '%ls'\n"
msgstr "%ls : Valeur --min-args '%ls' invalide\n"
#
#, c-format
msgid "%ls: Invalid --unknown-arguments value '%ls'\n"
msgstr ""
@@ -802,7 +804,6 @@ msgstr ""
msgid "%ls: expected a numeric value"
msgstr "%ls : valeur numérique attendue"
#
#, c-format
msgid "%ls: fish was not built with embedded files"
msgstr ""
@@ -899,17 +900,14 @@ msgstr ""
msgid "%s"
msgstr ""
#
#, c-format
msgid "%s %s: unrecognized feature '%ls'"
msgstr ""
#
#, c-format
msgid "%s and %s are mutually exclusive"
msgstr ""
#
#, c-format
msgid "%s could not read response to Primary Device Attribute query after waiting for %d seconds. This is often due to a missing feature in your terminal. See 'help terminal-compatibility' or 'man fish-terminal-compatibility'. This %s process will no longer wait for outstanding queries, which disables some optional features."
msgstr ""
@@ -1013,7 +1011,6 @@ msgstr "Une erreur est survenue lors du paramétrage du tube"
msgid "Argument is not a number: '%ls'"
msgstr ""
#
msgid "Await background process completion"
msgstr ""
@@ -1218,7 +1215,6 @@ msgstr ""
msgid "Failed to assign shell to its own process group"
msgstr ""
#
#, c-format
msgid "Failed to set terminal mode (%s)"
msgstr ""
@@ -1622,7 +1618,6 @@ msgstr "Arrêter la fonction actuellement en évaluation"
msgid "Stop the innermost loop"
msgstr "Arrêter la boucle interne"
#
msgid "Synchronized file access"
msgstr ""
@@ -1837,7 +1832,6 @@ msgstr "Les variables ne peuvent être placées entre crochets. Dans fish, veuil
msgid "Variables cannot be bracketed. In fish, please use {$%ls}."
msgstr "Les variables ne peuvent être placées entre crochets. Dans fish, veuillez utiliser {$%ls}."
#
msgid "Virtual timer expired"
msgstr ""
@@ -2001,7 +1995,9 @@ msgstr ""
msgid "|& is not valid. In fish, use &| to pipe both stdout and stderr."
msgstr ""
# fish-section-tier1-from-script-explicitly-added
msgid "fish-section-tier1-from-script-explicitly-added"
msgstr ""
msgid "%ls: %ls: expected %d arguments; got %d\\n"
msgstr ""
@@ -2224,7 +2220,9 @@ msgstr "ou le fichier était vide"
msgid "python executable not found"
msgstr "Exécutable python introuvable"
# fish-section-tier1-from-script-implicitly-added
msgid "fish-section-tier1-from-script-implicitly-added"
msgstr ""
msgid "# comments"
msgstr ""
@@ -3926,7 +3924,12 @@ msgstr ""
msgid "~ expansion"
msgstr ""
# fish-section-tier3-from-script-implicitly-added
msgid "fish-section-tier3-from-script-explicitly-added"
msgstr ""
msgid "fish-section-tier3-from-script-implicitly-added"
msgstr ""
msgid " "
msgstr ""

View File

@@ -1,6 +1,9 @@
# fish-note-sections: Translations are divided into sections, each starting with a fish-section-* comment.
# fish-note-sections: The first few sections are more important.
# fish-note-sections: Ignore the tier3 sections unless you have a lot of time.
# fish-note: To subscribe to proposed updates, point your feed reader at:
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/pl-additions.atom
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/pl-removals.atom
# fish-note: Translations are divided into sections, each starting with a fish-section-* pseudo-message.
# fish-note: The first few sections are more important.
# fish-note: Ignore the tier3 sections unless you have a lot of time.
# Translation of fish in Polish
# This file is distributed under the same license as the fish package.
# Author: m4sk1n <m4sk1n@vivaldi.net>
@@ -17,13 +20,15 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: GlotPress/2.2.2\n"
msgid "fish-section-tier1-from-rust"
msgstr ""
msgid ""
"\n"
" PID Command\n"
msgstr ""
#, c-format
# fish-section-tier1-from-rust
msgid " (%ls)\n"
msgstr ""
@@ -194,7 +199,6 @@ msgstr ""
msgid "%ls: %ls: invalid variable name. See `help identifiers`\n"
msgstr ""
#
#, c-format
msgid "%ls: %ls: option does not take an argument\n"
msgstr ""
@@ -375,7 +379,6 @@ msgstr "%ls: Oczekiwano dokładnie dwóch nazw (nazwa obecnej funkcji i nazwa no
msgid "%ls: Expected generic | variable | signal | exit | job-id for --handlers-type\n"
msgstr ""
#
#, c-format
msgid "%ls: Function '%ls' already exists. Cannot create copy of '%ls'\n"
msgstr ""
@@ -404,7 +407,6 @@ msgstr ""
msgid "%ls: Invalid --min-args value '%ls'\n"
msgstr ""
#
#, c-format
msgid "%ls: Invalid --unknown-arguments value '%ls'\n"
msgstr ""
@@ -697,7 +699,6 @@ msgstr ""
msgid "%ls: expected a numeric value"
msgstr "%ls: oczekiwano wartości liczbowej"
#
#, c-format
msgid "%ls: fish was not built with embedded files"
msgstr ""
@@ -794,17 +795,14 @@ msgstr ""
msgid "%s"
msgstr ""
#
#, c-format
msgid "%s %s: unrecognized feature '%ls'"
msgstr ""
#
#, c-format
msgid "%s and %s are mutually exclusive"
msgstr ""
#
#, c-format
msgid "%s could not read response to Primary Device Attribute query after waiting for %d seconds. This is often due to a missing feature in your terminal. See 'help terminal-compatibility' or 'man fish-terminal-compatibility'. This %s process will no longer wait for outstanding queries, which disables some optional features."
msgstr ""
@@ -908,7 +906,6 @@ msgstr ""
msgid "Argument is not a number: '%ls'"
msgstr ""
#
msgid "Await background process completion"
msgstr ""
@@ -1113,7 +1110,6 @@ msgstr ""
msgid "Failed to assign shell to its own process group"
msgstr ""
#
#, c-format
msgid "Failed to set terminal mode (%s)"
msgstr ""
@@ -1517,7 +1513,6 @@ msgstr "Zatrzymaj obecnie używaną funkcję"
msgid "Stop the innermost loop"
msgstr ""
#
msgid "Synchronized file access"
msgstr ""
@@ -1732,7 +1727,6 @@ msgstr "Zmienne nie mogą znajdować się w nawiasach. W fish używane jest \"$%
msgid "Variables cannot be bracketed. In fish, please use {$%ls}."
msgstr "Zmienne nie mogą znajdować się w nawiasach. W fish używane jest {$%ls}."
#
msgid "Virtual timer expired"
msgstr ""
@@ -1896,7 +1890,9 @@ msgstr ""
msgid "|& is not valid. In fish, use &| to pipe both stdout and stderr."
msgstr ""
# fish-section-tier1-from-script-explicitly-added
msgid "fish-section-tier1-from-script-explicitly-added"
msgstr ""
msgid "%ls: %ls: expected %d arguments; got %d\\n"
msgstr ""
@@ -2119,7 +2115,9 @@ msgstr ""
msgid "python executable not found"
msgstr ""
# fish-section-tier1-from-script-implicitly-added
msgid "fish-section-tier1-from-script-implicitly-added"
msgstr ""
msgid "# comments"
msgstr ""
@@ -3821,7 +3819,12 @@ msgstr ""
msgid "~ expansion"
msgstr ""
# fish-section-tier3-from-script-implicitly-added
msgid "fish-section-tier3-from-script-explicitly-added"
msgstr ""
msgid "fish-section-tier3-from-script-implicitly-added"
msgstr ""
msgid " "
msgstr ""

View File

@@ -1,6 +1,9 @@
# fish-note-sections: Translations are divided into sections, each starting with a fish-section-* comment.
# fish-note-sections: The first few sections are more important.
# fish-note-sections: Ignore the tier3 sections unless you have a lot of time.
# fish-note: To subscribe to proposed updates, point your feed reader at:
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/pt_BR-additions.atom
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/pt_BR-removals.atom
# fish-note: Translations are divided into sections, each starting with a fish-section-* pseudo-message.
# fish-note: The first few sections are more important.
# fish-note: Ignore the tier3 sections unless you have a lot of time.
# Portuguese translations for fish package.
# Copyright (C) 2014 THE fish'S COPYRIGHT HOLDER
# This file is distributed under the same license as the fish package.
@@ -22,13 +25,15 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 1.8.4\n"
msgid "fish-section-tier1-from-rust"
msgstr ""
msgid ""
"\n"
" PID Command\n"
msgstr ""
#, c-format
# fish-section-tier1-from-rust
msgid " (%ls)\n"
msgstr ""
@@ -199,7 +204,6 @@ msgstr ""
msgid "%ls: %ls: invalid variable name. See `help identifiers`\n"
msgstr ""
#
#, c-format
msgid "%ls: %ls: option does not take an argument\n"
msgstr ""
@@ -380,7 +384,6 @@ msgstr "%ls: Esperava exatamente dois nomes (nome atual da função, e novo nome
msgid "%ls: Expected generic | variable | signal | exit | job-id for --handlers-type\n"
msgstr ""
#
#, c-format
msgid "%ls: Function '%ls' already exists. Cannot create copy of '%ls'\n"
msgstr ""
@@ -409,7 +412,6 @@ msgstr ""
msgid "%ls: Invalid --min-args value '%ls'\n"
msgstr ""
#
#, c-format
msgid "%ls: Invalid --unknown-arguments value '%ls'\n"
msgstr ""
@@ -702,7 +704,6 @@ msgstr ""
msgid "%ls: expected a numeric value"
msgstr "%ls: esperava valor numérico"
#
#, c-format
msgid "%ls: fish was not built with embedded files"
msgstr ""
@@ -799,17 +800,14 @@ msgstr ""
msgid "%s"
msgstr ""
#
#, c-format
msgid "%s %s: unrecognized feature '%ls'"
msgstr ""
#
#, c-format
msgid "%s and %s are mutually exclusive"
msgstr ""
#
#, c-format
msgid "%s could not read response to Primary Device Attribute query after waiting for %d seconds. This is often due to a missing feature in your terminal. See 'help terminal-compatibility' or 'man fish-terminal-compatibility'. This %s process will no longer wait for outstanding queries, which disables some optional features."
msgstr ""
@@ -913,7 +911,6 @@ msgstr "Ocorreu um erro ao preparar pipe"
msgid "Argument is not a number: '%ls'"
msgstr ""
#
msgid "Await background process completion"
msgstr ""
@@ -1118,7 +1115,6 @@ msgstr ""
msgid "Failed to assign shell to its own process group"
msgstr ""
#
#, c-format
msgid "Failed to set terminal mode (%s)"
msgstr ""
@@ -1522,7 +1518,6 @@ msgstr "Pára a função em execução"
msgid "Stop the innermost loop"
msgstr "Pára o laço mais interno"
#
msgid "Synchronized file access"
msgstr ""
@@ -1737,7 +1732,6 @@ msgstr ""
msgid "Variables cannot be bracketed. In fish, please use {$%ls}."
msgstr ""
#
msgid "Virtual timer expired"
msgstr ""
@@ -1901,7 +1895,9 @@ msgstr ""
msgid "|& is not valid. In fish, use &| to pipe both stdout and stderr."
msgstr ""
# fish-section-tier1-from-script-explicitly-added
msgid "fish-section-tier1-from-script-explicitly-added"
msgstr ""
msgid "%ls: %ls: expected %d arguments; got %d\\n"
msgstr ""
@@ -2124,7 +2120,9 @@ msgstr ""
msgid "python executable not found"
msgstr "executável python não encontrado"
# fish-section-tier1-from-script-implicitly-added
msgid "fish-section-tier1-from-script-implicitly-added"
msgstr ""
msgid "# comments"
msgstr ""
@@ -3826,7 +3824,12 @@ msgstr ""
msgid "~ expansion"
msgstr ""
# fish-section-tier3-from-script-implicitly-added
msgid "fish-section-tier3-from-script-explicitly-added"
msgstr ""
msgid "fish-section-tier3-from-script-implicitly-added"
msgstr ""
msgid " "
msgstr ""
@@ -19604,11 +19607,6 @@ msgstr ""
msgid "Do not list files that match the given pattern"
msgstr ""
# Notas:
# Adicionar nota
#
# Caminhos:
# share/functions/__fish_complete_ls.fish:49
msgid "Do not list implied entries matching specified shell pattern"
msgstr "Não lista entradas com o padrão especificado"
@@ -26017,11 +26015,6 @@ msgstr ""
msgid "File is on filesystem of specified type"
msgstr ""
# Notas:
# Adicionar nota
#
# Caminhos:
# share/functions/__fish_complete_ls.fish:49
msgid "File is symlink matching specified case insensitive pattern"
msgstr ""
@@ -36558,12 +36551,6 @@ msgstr ""
msgid "Machine-readable description of custom origin"
msgstr ""
# Notas:
# Adicionar nota
#
# Caminhos:
# proc.cpp:1279
# proc.cpp:1305
msgid "Mail address to send alerts to"
msgstr ""
@@ -46062,12 +46049,6 @@ msgstr ""
msgid "Process last file first"
msgstr ""
# Notas:
# Adicionar nota
#
# Caminhos:
# proc.cpp:1279
# proc.cpp:1305
msgid "Process log file"
msgstr ""

View File

@@ -1,6 +1,9 @@
# fish-note-sections: Translations are divided into sections, each starting with a fish-section-* comment.
# fish-note-sections: The first few sections are more important.
# fish-note-sections: Ignore the tier3 sections unless you have a lot of time.
# fish-note: To subscribe to proposed updates, point your feed reader at:
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/sv-additions.atom
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/sv-removals.atom
# fish-note: Translations are divided into sections, each starting with a fish-section-* pseudo-message.
# fish-note: The first few sections are more important.
# fish-note: Ignore the tier3 sections unless you have a lot of time.
# Copyright © 2006
# This file is distributed under the same license as the fish package.
# Axel Liljencrantz <liljencrantz@gmail.com>, 2006
@@ -18,13 +21,15 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "fish-section-tier1-from-rust"
msgstr ""
msgid ""
"\n"
" PID Command\n"
msgstr ""
#, c-format
# fish-section-tier1-from-rust
msgid " (%ls)\n"
msgstr ""
@@ -195,7 +200,6 @@ msgstr ""
msgid "%ls: %ls: invalid variable name. See `help identifiers`\n"
msgstr ""
#
#, c-format
msgid "%ls: %ls: option does not take an argument\n"
msgstr ""
@@ -376,7 +380,6 @@ msgstr ""
msgid "%ls: Expected generic | variable | signal | exit | job-id for --handlers-type\n"
msgstr ""
#
#, c-format
msgid "%ls: Function '%ls' already exists. Cannot create copy of '%ls'\n"
msgstr ""
@@ -405,7 +408,6 @@ msgstr ""
msgid "%ls: Invalid --min-args value '%ls'\n"
msgstr ""
#
#, c-format
msgid "%ls: Invalid --unknown-arguments value '%ls'\n"
msgstr ""
@@ -698,7 +700,6 @@ msgstr ""
msgid "%ls: expected a numeric value"
msgstr ""
#
#, c-format
msgid "%ls: fish was not built with embedded files"
msgstr ""
@@ -795,17 +796,14 @@ msgstr ""
msgid "%s"
msgstr ""
#
#, c-format
msgid "%s %s: unrecognized feature '%ls'"
msgstr ""
#
#, c-format
msgid "%s and %s are mutually exclusive"
msgstr ""
#
#, c-format
msgid "%s could not read response to Primary Device Attribute query after waiting for %d seconds. This is often due to a missing feature in your terminal. See 'help terminal-compatibility' or 'man fish-terminal-compatibility'. This %s process will no longer wait for outstanding queries, which disables some optional features."
msgstr ""
@@ -909,7 +907,6 @@ msgstr "Ett fel inträffade under skapandet av ett rör"
msgid "Argument is not a number: '%ls'"
msgstr ""
#
msgid "Await background process completion"
msgstr ""
@@ -1114,7 +1111,6 @@ msgstr ""
msgid "Failed to assign shell to its own process group"
msgstr ""
#
#, c-format
msgid "Failed to set terminal mode (%s)"
msgstr ""
@@ -1518,7 +1514,6 @@ msgstr "Avbryt den nuvarande funktionen"
msgid "Stop the innermost loop"
msgstr "Avbryt den innersta loopen"
#
msgid "Synchronized file access"
msgstr ""
@@ -1733,7 +1728,6 @@ msgstr ""
msgid "Variables cannot be bracketed. In fish, please use {$%ls}."
msgstr ""
#
msgid "Virtual timer expired"
msgstr ""
@@ -1897,7 +1891,9 @@ msgstr ""
msgid "|& is not valid. In fish, use &| to pipe both stdout and stderr."
msgstr ""
# fish-section-tier1-from-script-explicitly-added
msgid "fish-section-tier1-from-script-explicitly-added"
msgstr ""
msgid "%ls: %ls: expected %d arguments; got %d\\n"
msgstr ""
@@ -2069,14 +2065,12 @@ msgstr ""
msgid "Too many args for cd command"
msgstr ""
#
msgid "Type %shelp%s for instructions on how to use fish"
msgstr "Skriv %shelp%s för instruktioner om hur man använder fish"
msgid "Warning: the file containing this function has not been saved. Changes may be lost when fish is closed."
msgstr ""
#
msgid "Welcome to fish, the friendly interactive shell"
msgstr "Välkommen till fish, det vänliga interaktiva skalet"
@@ -2122,7 +2116,9 @@ msgstr ""
msgid "python executable not found"
msgstr ""
# fish-section-tier1-from-script-implicitly-added
msgid "fish-section-tier1-from-script-implicitly-added"
msgstr ""
msgid "# comments"
msgstr ""
@@ -3824,7 +3820,12 @@ msgstr ""
msgid "~ expansion"
msgstr ""
# fish-section-tier3-from-script-implicitly-added
msgid "fish-section-tier3-from-script-explicitly-added"
msgstr ""
msgid "fish-section-tier3-from-script-implicitly-added"
msgstr ""
msgid " "
msgstr ""

View File

@@ -1,20 +1,10 @@
# fish-note-sections: Translations are divided into sections, each starting with a fish-section-* comment.
# fish-note-sections: The first few sections are more important.
# fish-note-sections: Ignore the tier3 sections unless you have a lot of time.
msgid ""
msgstr ""
"Project-Id-Version: fish 1.21.8\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-10 16:38+0100\n"
"PO-Revision-Date: 2025-09-30 19:14+0800\n"
"Last-Translator: Yuyi Wang <Strawberry_Str@hotmail.com>\n"
"Language-Team: \n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.7\n"
# fish-note: To subscribe to proposed updates, point your feed reader at:
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/zh_CN-additions.atom
# fish-note: https://raw.githubusercontent.com/fish-shell/fish-shell/fish-shell-events/po/zh_CN-removals.atom
# fish-note: Translations are divided into sections, each starting with a fish-section-* pseudo-message.
# fish-note: The first few sections are more important.
# fish-note: Ignore the tier3 sections unless you have a lot of time.
#
# General Notices 凡例
# abort: 中止
# argument: 参数
@@ -41,6 +31,23 @@ msgstr ""
# token: 记号
# universal (variable): 通用
# valid & invalid: 有效 & 无效
msgid ""
msgstr ""
"Project-Id-Version: fish 1.21.8\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-10 16:38+0100\n"
"PO-Revision-Date: 2025-09-30 19:14+0800\n"
"Last-Translator: Yuyi Wang <Strawberry_Str@hotmail.com>\n"
"Language-Team: \n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.7\n"
msgid "fish-section-tier1-from-rust"
msgstr ""
msgid ""
"\n"
" PID Command\n"
@@ -49,7 +56,6 @@ msgstr ""
" PID 命令\n"
#, c-format
# fish-section-tier1-from-rust
msgid " (%ls)\n"
msgstr " (%ls)\n"
@@ -1917,7 +1923,9 @@ msgstr "无限制\n"
msgid "|& is not valid. In fish, use &| to pipe both stdout and stderr."
msgstr "|& 无效。在 fish 中,用 &| 来同时管道链接 stdout 和 stderr。"
# fish-section-tier1-from-script-explicitly-added
msgid "fish-section-tier1-from-script-explicitly-added"
msgstr ""
msgid "%ls: %ls: expected %d arguments; got %d\\n"
msgstr "%ls: %ls: 期望 %d 个参数;收到 %d 个\\n"
@@ -2140,7 +2148,9 @@ msgstr "或文件为空"
msgid "python executable not found"
msgstr "找不到 python 可执行文件"
# fish-section-tier1-from-script-implicitly-added
msgid "fish-section-tier1-from-script-implicitly-added"
msgstr ""
msgid "# comments"
msgstr "# 注释"
@@ -3666,7 +3676,7 @@ msgid "What characters are allowed in names"
msgstr "名称中允许什么字符"
msgid "What set -x does"
msgstr "设置 -x 做什么"
msgstr "`set -x` 做什么"
msgid "Where to direct debug output to"
msgstr "将调试输出导向何处"
@@ -3842,7 +3852,12 @@ msgstr "{a,b} 大括号展开"
msgid "~ expansion"
msgstr "~ 展开"
# fish-section-tier3-from-script-implicitly-added
msgid "fish-section-tier3-from-script-explicitly-added"
msgstr ""
msgid "fish-section-tier3-from-script-implicitly-added"
msgstr ""
msgid " "
msgstr " "
@@ -40048,7 +40063,7 @@ msgid "Operate quietly and do not report progress"
msgstr "安静操作,不报告进度"
msgid "Operate recursively"
msgstr "递归操"
msgstr "递归操"
msgid "Operate recursively on datasets"
msgstr "在数据集上递归操作"

View File

@@ -47,7 +47,7 @@ complete -c scp -d "Local Path" -n "not string match @ -- (commandline -ct)"
complete -c scp -d "Remote Path" -f -n "commandline -ct | string match -e ':'" -a '
(__scp_remote_target):(
if not set -q __fish_scp_sftp
set -l tmp (__fish_mktemp_relative fish-scp)
set -l tmp (__fish_mktemp fish-scp)
if scp -P(__scp2ssh_port_number) -o "BatchMode yes" -q -O $tmp (__scp_remote_target):/dev/null
set -g __fish_scp_sftp true
else

View File

@@ -10,8 +10,7 @@ set -l erase_line "$(
function __fish_echo --inherit-variable erase_line --description 'run the given command after the current commandline and redraw the prompt'
set -l line (commandline --line)
string >&2 repeat -N \n --count=(math (commandline | count) - $line + 1)
printf %s $erase_line >&2
$argv >&2
printf %s\n $erase_line($argv) >&2
string >&2 repeat -N \n --count=(math (count (fish_prompt)) - 1)
string >&2 repeat -N \n --count=(math $line - 1)
commandline -f repaint

View File

@@ -87,11 +87,11 @@ function fish_config --description "Launch fish's web based configuration"
return 1
end
set -l prompt_dir $__fish_data_dir/sample_prompts $__fish_data_dir/tools/web_config/sample_prompts
set -l prompt_dir $__fish_data_dir/tools/web_config/sample_prompts
switch $cmd
case show
set -l fish (status fish-path)
set -l prompts (dirs=$prompt_dir __fish_config_matching tools/web_config/sample_prompts .fish $argv)
set -l prompts (__fish_config_matching tools/web_config/sample_prompts .fish $argv)
for p in $prompts
set -l promptname (string replace -r '.*/([^/]*).fish$' '$1' $p)
echo -s (set_color --underline) $promptname (set_color normal)
@@ -240,7 +240,8 @@ function fish_config --description "Launch fish's web based configuration"
case show
set -l fish (status fish-path)
set -l themes \
(dirs=$dirs __fish_config_matching tools/web_config/themes .theme $argv)
(path filter $dirs/$argv.theme) \
(__fish_config_matching tools/web_config/themes .theme $argv)
set -l used_themes
echo -s (set_color normal; set_color --underline) Current (set_color normal)
@@ -383,16 +384,17 @@ function __fish_config_matching
set -l suffix $argv[2]
set -e argv[1..2]
set -l paths
if not set -q argv[1]
set paths $dirs/*$suffix
else
set paths (path filter $dirs/$argv$suffix)
end
if not set -q __fish_data_dir[1]
if set -q __fish_data_dir[1]
if not set -q argv[1]
set -a paths (status list-files $prefix)
set paths $__fish_data_dir/$prefix/*$suffix
else
set -a paths (status list-files $prefix | grep -Fx -e"$prefix/"$argv$suffix)
set paths (path filter $__fish_data_dir/$prefix/$argv$suffix)
end
else
if not set -q argv[1]
set paths (status list-files $prefix)
else
set paths (status list-files $prefix | grep -Fx -e"$prefix/"$argv$suffix)
end
end
string join \n $paths

View File

@@ -229,7 +229,7 @@ def parse_color(color_str):
background_color = ""
underline_color = ""
bold = False
underline = None
underline = False
italics = False
dim = False
reverse = False
@@ -263,10 +263,6 @@ def parse_color(color_str):
) -> str:
if comp.startswith(long_opt):
c = comp[len(long_opt) :]
if c[0] == "=":
# There was a = between the long option and the value.
# i.e. support also --background=red, not just --background red
c = c[1:]
parsed_c = parse_one_color(c)
# We prefer the unparsed version - if it says "brgreen", we use brgreen,
# instead of 00ff00

View File

@@ -635,7 +635,7 @@ pub fn commandline(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr])
transient = parser.libdata().transient_commandline.clone().unwrap();
current_buffer = &transient;
current_cursor_pos = transient.len();
} else if parser.interactive_initialized.load() || is_interactive_session() {
} else if is_interactive_session() {
current_buffer = &rstate.text;
current_cursor_pos = rstate.cursor_pos;
} else {

View File

@@ -458,7 +458,7 @@ pub fn complete(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) ->
None => {
// No argument given, try to use the current commandline.
let commandline_state = commandline_get_state(true);
if !parser.interactive_initialized.load() && !is_interactive_session() {
if !is_interactive_session() {
streams.err.append(cmd);
streams
.err

View File

@@ -32,8 +32,6 @@
use std::sync::{Arc, MutexGuard};
use std::time;
pub const BUILD_DIR: &str = env!("FISH_RESOLVED_BUILD_DIR");
pub const PACKAGE_NAME: &str = env!("CARGO_PKG_NAME");
// Highest legal ASCII value.
@@ -1656,7 +1654,7 @@ pub fn get_executable_path(argv0: impl AsRef<Path>) -> PathBuf {
// When /proc/self/exe points to a file that was deleted (or overwritten on update!)
// then linux adds a " (deleted)" suffix.
// If that's not a valid path, let's remove that awkward suffix.
if path.as_os_str().as_bytes().ends_with(b" (deleted)") {
if !path.ends_with(" (deleted)") {
return path;
}

View File

@@ -1,7 +1,7 @@
use crate::common::wcs2string;
use crate::common::BUILD_DIR;
use crate::wchar::prelude::*;
use crate::{common::get_executable_path, FLOG, FLOGF};
#[cfg(not(feature = "embed-data"))]
use fish_build_helper::workspace_root;
use std::ffi::OsString;
use std::os::unix::ffi::OsStringExt;
@@ -63,14 +63,7 @@ fn static_paths() -> Self {
fn from_exec_path(exec_path: PathBuf) -> Self {
FLOG!(config, "embed-data feature is active, ignoring data paths");
Self {
sysconf: if exec_path
.canonicalize()
.is_ok_and(|exec_path| exec_path.starts_with(BUILD_DIR))
{
workspace_root().join("etc")
} else {
PathBuf::from(SYSCONF_DIR).join("fish")
},
sysconf: PathBuf::from(SYSCONF_DIR).join("fish"),
bin: exec_path.parent().map(|x| x.to_path_buf()),
}
}
@@ -123,7 +116,7 @@ fn from_exec_path(unresolved_exec_path: PathBuf) -> Self {
}
// If we're in Cargo's target directory or in CMake's build directory, use the source files.
if exec_path.starts_with(BUILD_DIR) {
if exec_path.starts_with(env!("FISH_BUILD_DIR")) {
FLOG!(
config,
format!(

View File

@@ -452,8 +452,6 @@ fn update_fish_color_support(vars: &EnvStack) {
crate::terminal::set_color_support(color_support);
}
pub const MIDNIGHT_COMMANDER_SID: &wstr = L!("MC_SID");
// Initialize the terminal subsystem
fn init_terminal(vars: &EnvStack) {
let term = vars.get(L!("TERM"));
@@ -466,7 +464,7 @@ fn init_terminal(vars: &EnvStack) {
IS_DUMB.store(term == "dumb");
ONLY_GRAYSCALE.store(term == "ansi-m" || term == "linux-m" || term == "xterm-mono");
if vars.get(MIDNIGHT_COMMANDER_SID).is_some() {
if vars.get(L!("MC_SID")).is_some() {
screen_set_midnight_commander_hack();
}

View File

@@ -12,8 +12,8 @@
use crate::reader::reader_test_and_clear_interrupted;
use crate::threads::iothread_port;
use crate::tty_handoff::{
maybe_set_kitty_keyboard_capability, maybe_set_scroll_content_up_capability,
SCROLL_CONTENT_UP_TERMINFO_CODE, XTVERSION,
get_kitty_keyboard_capability, maybe_set_kitty_keyboard_capability,
maybe_set_scroll_content_up_capability, SCROLL_CONTENT_UP_TERMINFO_CODE, XTVERSION,
};
use crate::universal_notifier::default_notifier;
use crate::wchar::{encode_byte_to_char, prelude::*};
@@ -983,13 +983,16 @@ fn try_readb(&mut self, buffer: &mut Vec<u8>) -> Option<u8> {
let fd = self.get_in_fd();
if !check_fd_readable(
fd,
Duration::from_millis(if self.paste_is_buffering() || self.is_blocked_querying() {
300
} else if buffer == b"\x1b" {
1 // distinguish legacy escape
} else {
30
}),
Duration::from_millis(
if self.paste_is_buffering()
|| self.is_blocked_querying()
|| get_kitty_keyboard_capability() == Some(&true)
{
300
} else {
1
},
),
) {
FLOG!(
reader,

View File

@@ -585,10 +585,10 @@ fn make_base_directory(xdg_var: &wstr, non_xdg_homepath: &wstr) -> BaseDirectory
// the actual $HOME or $XDG_XXX directories. This prevents the tests from failing and/or stops
// the tests polluting the user's actual $HOME if a sandbox environment has not been set up.
{
use crate::common::{str2wcstring, BUILD_DIR};
use crate::common::str2wcstring;
use std::path::PathBuf;
let mut build_dir = PathBuf::from(BUILD_DIR);
let mut build_dir = PathBuf::from(env!("FISH_BUILD_DIR"));
build_dir.push("fish-test-home");
let err = match std::fs::create_dir_all(&build_dir) {

View File

@@ -66,7 +66,6 @@
use crate::env::EnvStack;
use crate::env::{EnvMode, Environment, Statuses};
use crate::env_dispatch::guess_emoji_width;
use crate::env_dispatch::MIDNIGHT_COMMANDER_SID;
use crate::exec::exec_subshell;
use crate::expand::expand_one;
use crate::expand::{expand_string, expand_tilde, ExpandFlags, ExpandResultCode};
@@ -261,9 +260,9 @@ fn redirect_tty_after_sighup() {
}
}
fn querying_allowed(vars: &dyn Environment) -> bool {
fn querying_allowed() -> bool {
future_feature_flags::test(FeatureFlag::query_term) &&
!is_dumb() && vars.get(MIDNIGHT_COMMANDER_SID).is_none()
!is_dumb() && std::env::var_os("MC_TMPDIR").is_none()
// Could use /dev/tty in future.
&& isatty(STDOUT_FILENO)
}
@@ -279,10 +278,10 @@ pub fn terminal_init(vars: &dyn Environment, inputfd: RawFd) -> InputEventQueue
);
let _init_tty_metadata = ScopeGuard::new((), |()| {
initialize_tty_protocols(vars);
initialize_tty_protocols();
});
if !querying_allowed(vars) {
if !querying_allowed() {
return input_queue;
}
@@ -1587,7 +1586,7 @@ pub fn mouse_left_click(&mut self, cursor: ViewportPosition, click_position: Vie
self.pager.selected_completion_idx = Some(idx);
self.pager_selection_changed();
}
CharOffset::Pager(_) | CharOffset::None => {}
_ => {}
}
}
}
@@ -1645,7 +1644,7 @@ pub fn combine_command_and_autosuggestion(
impl<'a> Reader<'a> {
pub fn request_cursor_position(&mut self, out: &mut Outputter, q: CursorPositionQuery) {
if !querying_allowed(self.vars()) {
if !querying_allowed() {
return;
}
let mut query = self.blocking_query();
@@ -2630,11 +2629,9 @@ fn handle_char_event(&mut self, injected_event: Option<CharEvent>) -> ControlFlo
ImplicitEvent::QueryInterrupted => (),
ImplicitEvent::FocusIn => {
event::fire_generic(self.parser, L!("fish_focus_in").to_owned(), vec![]);
self.save_screen_state();
}
ImplicitEvent::FocusOut => {
event::fire_generic(self.parser, L!("fish_focus_out").to_owned(), vec![]);
self.save_screen_state();
}
ImplicitEvent::DisableMouseTracking => {
Outputter::stdoutput()

View File

@@ -629,26 +629,8 @@ pub fn offset_in_cmdline_given_cursor(
0
});
let y = y.min(self.actual.line_count() - 1);
let Some(viewport_prompt_x) = viewport_cursor.x.checked_sub(self.actual.cursor.x) else {
FLOGF!(
reader,
"Actual cursor x=%d exceeds reported cursor x=%d, \
was the cursor moved by printing to the TTY?",
self.actual.cursor.x,
viewport_cursor.x
);
return CharOffset::None;
};
let Some(x) = viewport_position.x.checked_sub(viewport_prompt_x) else {
FLOGF!(
reader,
"Computed prompt x=%d exceeds mouse click x=%d, \
was the cursor moved by printing to the TTY?",
viewport_prompt_x,
viewport_position.x
);
return CharOffset::None;
};
let viewport_prompt_x = viewport_cursor.x - self.actual.cursor.x;
let x = viewport_position.x - viewport_prompt_x;
let line = self.actual.line(y);
let x = x.max(line.indentation);
let offset = line

View File

@@ -29,7 +29,7 @@
mod wgetopt;
pub mod prelude {
use crate::common::{ScopeGuard, ScopeGuarding, BUILD_DIR};
use crate::common::{ScopeGuard, ScopeGuarding};
use crate::env::{env_init, misc_init};
use crate::parser::{CancelBehavior, Parser};
use crate::reader::{reader_deinit, reader_init};
@@ -88,9 +88,9 @@ fn deref(&self) -> &Self::Target {
pub fn test_init() -> impl ScopeGuarding<Target = ()> {
static DONE: OnceCell<()> = OnceCell::new();
DONE.get_or_init(|| {
// If we are building with `cargo build` and have build w/ `cmake`, this might not
// yet exist.
let mut test_dir = PathBuf::from(BUILD_DIR);
// If we are building with `cargo build` and have build w/ `cmake`, FISH_BUILD_DIR might
// not yet exist.
let mut test_dir = PathBuf::from(env!("FISH_BUILD_DIR"));
test_dir.push("fish-test");
std::fs::create_dir_all(&test_dir).unwrap();
set_current_dir(&test_dir).unwrap();

View File

@@ -2,8 +2,6 @@
//! and reclaiming it after.
use crate::common::{self, safe_write_loop};
use crate::env::Environment;
use crate::env_dispatch::MIDNIGHT_COMMANDER_SID;
use crate::flog::{FLOG, FLOGF};
use crate::global_safety::RelaxedAtomicBool;
use crate::job_group::JobGroup;
@@ -27,6 +25,11 @@
/// Whether kitty keyboard protocol support is present in the TTY.
static KITTY_KEYBOARD_SUPPORTED: OnceCell<bool> = OnceCell::new();
/// Get whether the TTY supports the kitty keyboard protocol.
pub fn get_kitty_keyboard_capability() -> Option<&'static bool> {
KITTY_KEYBOARD_SUPPORTED.get()
}
/// Set that the TTY supports the kitty keyboard protocol.
pub fn maybe_set_kitty_keyboard_capability() {
KITTY_KEYBOARD_SUPPORTED.get_or_init(|| true);
@@ -57,8 +60,6 @@ pub fn xtversion() -> Option<&'static wstr> {
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum TtyQuirks {
None,
// Running Midnight Commander which can't parse CSI yet.
PreCsiMidnightCommander,
// Running in iTerm2 before 3.5.12, which causes issues when using the kitty keyboard protocol.
PreKittyIterm2,
// Whether we are running under tmux.
@@ -69,13 +70,9 @@ pub enum TtyQuirks {
impl TtyQuirks {
// Create a new TtyQuirks instance with the current environment.
fn detect(vars: &dyn Environment, xtversion: &wstr) -> Self {
fn detect(xtversion: &wstr) -> Self {
use TtyQuirks::*;
if vars.get(MIDNIGHT_COMMANDER_SID).is_some()
&& vars.get(L!("__mc_kitty_keyboard")).is_none()
{
PreCsiMidnightCommander
} else if get_iterm2_version(xtversion).is_some_and(|v| v < (3, 5, 12)) {
if get_iterm2_version(xtversion).is_some_and(|v| v < (3, 5, 12)) {
PreKittyIterm2
} else if xtversion.starts_with(L!("tmux ")) {
Tmux
@@ -151,10 +148,7 @@ impl TtyQuirks {
// Determine which keyboard protocol.
// This is used from a signal handler.
fn safe_get_supported_protocol(&self) -> ProtocolKind {
use TtyQuirks::{PreCsiMidnightCommander, PreKittyIterm2, Wezterm};
if *self == PreCsiMidnightCommander {
return ProtocolKind::None;
}
use TtyQuirks::{PreKittyIterm2, Wezterm};
if *self == PreKittyIterm2 {
return ProtocolKind::Other;
}
@@ -238,7 +232,7 @@ fn tty_protocols() -> Option<&'static TtyProtocolsSet> {
}
// Initialize serialized commands for enabling/disabling TTY protocols in signal handlers.
pub fn initialize_tty_protocols(vars: &dyn Environment) {
pub fn initialize_tty_protocols() {
// Default missing query responses.
KITTY_KEYBOARD_SUPPORTED.get_or_init(|| false);
SCROLL_CONTENT_UP_SUPPORTED.get_or_init(|| false);
@@ -249,7 +243,7 @@ pub fn initialize_tty_protocols(vars: &dyn Environment) {
let mut p = TTY_PROTOCOLS.load(Acquire);
if p.is_null() {
// Try to swap in a new TTY protocols set.
p = Box::into_raw(Box::new(TtyQuirks::detect(vars, xtversion).get_protocols()));
p = Box::into_raw(Box::new(TtyQuirks::detect(xtversion).get_protocols()));
if let Err(_e) = TTY_PROTOCOLS.compare_exchange(std::ptr::null_mut(), p, Release, Acquire) {
// Safety: p comes from Box::into_raw right above,
// and wasn't shared with any other thread.

View File

@@ -1,12 +0,0 @@
# RUN: %fish -d config | grep -v ^Debug.enabled
# REQUIRES: %fish -c 'status build-info' | grep '^Features:.*embed-data'
# CHECKERR: config: executable path: {{.*}}/fish
# CHECKERR: config: embed-data feature is active, ignoring data paths
# NOTE: When our executable is located outside the workspace, this is "/etc".
# CHECKERR: config: paths.sysconf: {{.+}}/etc
# CHECKERR: config: paths.bin: {{.*}}
# CHECKERR: config: sourcing {{.+}}/etc/config.fish
# CHECKERR: config: not sourcing {{.*}}/xdg_config_home/fish/config.fish (not readable or does not exist)

View File

@@ -1,13 +1,13 @@
#RUN: %fish %s
# This still demos the current theme.
fish_config theme show non-existant-theme
fish_config theme show non-existent-theme
# CHECK: {{\x1b\[m}}{{\x1b\[4m}}Current{{\x1b\[m}}
# CHECK: /bright/vixens{{\x1b\[m}} jump{{\x1b\[m}} |{{\x1b\[m}} "fowl"{{\x1b\[m}} > quack{{\x1b\[m}} &{{\x1b\[m}} # This is a comment
# CHECK: {{\x1b\[m}}echo{{\x1b\[m}} 'Errors are the portal to discovery
# CHECK: {{\x1b\[m}}Th{{\x1b\[m}}is an autosuggestion
fish_config prompt show non-existant-prompt
fish_config prompt show non-existent-prompt
fish_config prompt show default
# CHECK: {{\x1b\[4m}}default{{\x1b\[m}}
@@ -23,21 +23,6 @@ fish_config theme show "fish default"
# CHECK: {{\x1b\[m}}{{\x1b\[m}}echo{{\x1b\[m}} {{\x1b\[91m}}'{{\x1b\[33m}}Errors are the portal to discovery
# CHECK: {{\x1b\[m}}{{\x1b\[m}}Th{{\x1b\[m}}{{\x1b\[90m}}is an autosuggestion
mkdir $__fish_config_dir/themes
touch $__fish_config_dir/themes/custom-from-userconf.theme
fish_config theme show | grep -E 'fish default|Default Dark|custom-from-userconf'
# CHECK: {{\x1b\[m}}{{\x1b\[4m}}custom-from-userconf{{\x1b\[m}}
fish_config theme show | grep -E 'fish default|Default Dark'
# CHECK: {{\x1b\[m}}{{\x1b\[4m}}Base16 Default Dark{{\x1b\[m}}
# CHECK: {{\x1b\[m}}{{\x1b\[4m}}fish default{{\x1b\[m}}
# Override a default theme with different colors.
{
status get-file tools/web_config/themes/None.theme 2>/dev/null ||
cat $__fish_data_dir/tools/web_config/themes/None.theme
} >$__fish_config_dir/themes/"fish default.theme"
fish_config theme show | grep -E 'fish default|Base16 Default Dark' -A1
# CHECK: {{\x1b\[m}}{{\x1b\[4m}}fish default{{\x1b\[m}}
# CHECK: {{\x1b\[m}}/bright/vixens{{\x1b\[m}} {{\x1b\[m}}jump{{\x1b\[m}}{{.*}}
# CHECK: --
# CHECK: {{\x1b\[m}}{{\x1b\[4m}}Base16 Default Dark{{\x1b\[m}}
# CHECK: {{.*}}/bright/vixens{{.*}}

View File

@@ -61,6 +61,7 @@ def makeenv(script_path: Path, home: Path) -> Dict[str, str]:
"XDG_DATA_DIRS",
"LANGUAGE",
"MC_SID",
"MC_TMPDIR",
"COLORTERM",
"KONSOLE_VERSION",
"STY",