mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Reformat
This commit is contained in:
parent
e30f661867
commit
2e55e34544
52 changed files with 370 additions and 239 deletions
|
@ -13,6 +13,7 @@ import re
|
||||||
import shlex
|
import shlex
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from itertools import zip_longest
|
from itertools import zip_longest
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -20,7 +21,7 @@ except ImportError:
|
||||||
from difflib import SequenceMatcher
|
from difflib import SequenceMatcher
|
||||||
|
|
||||||
# Directives can occur at the beginning of a line, or anywhere in a line that does not start with #.
|
# Directives can occur at the beginning of a line, or anywhere in a line that does not start with #.
|
||||||
COMMENT_RE = r'^(?:[^#].*)?#\s*'
|
COMMENT_RE = r"^(?:[^#].*)?#\s*"
|
||||||
|
|
||||||
# A regex showing how to run the file.
|
# A regex showing how to run the file.
|
||||||
RUN_RE = re.compile(COMMENT_RE + r"RUN:\s+(.*)\n")
|
RUN_RE = re.compile(COMMENT_RE + r"RUN:\s+(.*)\n")
|
||||||
|
@ -139,9 +140,10 @@ class Line(object):
|
||||||
ret = ret.replace("{", "{{").replace("}", "}}")
|
ret = ret.replace("{", "{{").replace("}", "}}")
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class RunCmd(object):
|
class RunCmd(object):
|
||||||
""" A command to run on a given Checker.
|
"""A command to run on a given Checker.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
args: Unexpanded shell command as a string.
|
args: Unexpanded shell command as a string.
|
||||||
"""
|
"""
|
||||||
|
@ -215,10 +217,16 @@ class TestFailure(object):
|
||||||
"",
|
"",
|
||||||
]
|
]
|
||||||
if self.error_annotation_lines:
|
if self.error_annotation_lines:
|
||||||
fields["error_annotation"] = " ".join([x.text for x in self.error_annotation_lines])
|
fields["error_annotation"] = " ".join(
|
||||||
fields["error_annotation_lineno"] = str(self.error_annotation_lines[0].number)
|
[x.text for x in self.error_annotation_lines]
|
||||||
|
)
|
||||||
|
fields["error_annotation_lineno"] = str(
|
||||||
|
self.error_annotation_lines[0].number
|
||||||
|
)
|
||||||
if len(self.error_annotation_lines) > 1:
|
if len(self.error_annotation_lines) > 1:
|
||||||
fields["error_annotation_lineno"] += ":" + str(self.error_annotation_lines[-1].number)
|
fields["error_annotation_lineno"] += ":" + str(
|
||||||
|
self.error_annotation_lines[-1].number
|
||||||
|
)
|
||||||
fmtstrs += [
|
fmtstrs += [
|
||||||
" additional output on stderr:{error_annotation_lineno}:",
|
" additional output on stderr:{error_annotation_lineno}:",
|
||||||
" {BOLD}{error_annotation}{RESET}",
|
" {BOLD}{error_annotation}{RESET}",
|
||||||
|
@ -229,14 +237,19 @@ class TestFailure(object):
|
||||||
lastcheckline = None
|
lastcheckline = None
|
||||||
for d in self.diff.get_grouped_opcodes():
|
for d in self.diff.get_grouped_opcodes():
|
||||||
for op, alo, ahi, blo, bhi in d:
|
for op, alo, ahi, blo, bhi in d:
|
||||||
color="{BOLD}"
|
color = "{BOLD}"
|
||||||
if op == 'replace' or op == 'delete':
|
if op == "replace" or op == "delete":
|
||||||
color="{RED}"
|
color = "{RED}"
|
||||||
# We got a new chunk, so we print a marker.
|
# We got a new chunk, so we print a marker.
|
||||||
if alo > lasthi:
|
if alo > lasthi:
|
||||||
fmtstrs += [
|
fmtstrs += [
|
||||||
" [...] from line " + str(self.checks[blo].line.number)
|
" [...] from line "
|
||||||
+ " (" + self.lines[alo].file + ":" + str(self.lines[alo].number) + "):"
|
+ str(self.checks[blo].line.number)
|
||||||
|
+ " ("
|
||||||
|
+ self.lines[alo].file
|
||||||
|
+ ":"
|
||||||
|
+ str(self.lines[alo].number)
|
||||||
|
+ "):"
|
||||||
]
|
]
|
||||||
lasthi = ahi
|
lasthi = ahi
|
||||||
|
|
||||||
|
@ -244,17 +257,41 @@ class TestFailure(object):
|
||||||
lastcheck = False
|
lastcheck = False
|
||||||
for a, b in zip_longest(self.lines[alo:ahi], self.checks[blo:bhi]):
|
for a, b in zip_longest(self.lines[alo:ahi], self.checks[blo:bhi]):
|
||||||
# Clean up strings for use in a format string - double up the curlies.
|
# Clean up strings for use in a format string - double up the curlies.
|
||||||
astr = color + a.escaped_text(for_formatting=True) + "{RESET}" if a else ""
|
astr = (
|
||||||
|
color + a.escaped_text(for_formatting=True) + "{RESET}"
|
||||||
|
if a
|
||||||
|
else ""
|
||||||
|
)
|
||||||
if b:
|
if b:
|
||||||
bstr = "'{BLUE}" + b.line.escaped_text(for_formatting=True) + "{RESET}'" + " on line " + str(b.line.number)
|
bstr = (
|
||||||
|
"'{BLUE}"
|
||||||
|
+ b.line.escaped_text(for_formatting=True)
|
||||||
|
+ "{RESET}'"
|
||||||
|
+ " on line "
|
||||||
|
+ str(b.line.number)
|
||||||
|
)
|
||||||
lastcheckline = b.line.number
|
lastcheckline = b.line.number
|
||||||
|
|
||||||
if op == 'equal':
|
if op == "equal":
|
||||||
fmtstrs += [" " + astr]
|
fmtstrs += [" " + astr]
|
||||||
elif b and a:
|
elif b and a:
|
||||||
fmtstrs += [" " + astr + " <= does not match " + b.type + " " + bstr]
|
fmtstrs += [
|
||||||
|
" "
|
||||||
|
+ astr
|
||||||
|
+ " <= does not match "
|
||||||
|
+ b.type
|
||||||
|
+ " "
|
||||||
|
+ bstr
|
||||||
|
]
|
||||||
elif b:
|
elif b:
|
||||||
fmtstrs += [" " + astr + " <= nothing to match " + b.type + " " + bstr]
|
fmtstrs += [
|
||||||
|
" "
|
||||||
|
+ astr
|
||||||
|
+ " <= nothing to match "
|
||||||
|
+ b.type
|
||||||
|
+ " "
|
||||||
|
+ bstr
|
||||||
|
]
|
||||||
elif not b:
|
elif not b:
|
||||||
string = " " + astr
|
string = " " + astr
|
||||||
if bhi == len(self.checks):
|
if bhi == len(self.checks):
|
||||||
|
@ -262,7 +299,10 @@ class TestFailure(object):
|
||||||
string += " <= no more checks"
|
string += " <= no more checks"
|
||||||
lastcheck = True
|
lastcheck = True
|
||||||
elif lastcheckline is not None:
|
elif lastcheckline is not None:
|
||||||
string += " <= no check matches this, previous check on line " + str(lastcheckline)
|
string += (
|
||||||
|
" <= no check matches this, previous check on line "
|
||||||
|
+ str(lastcheckline)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
string += " <= no check matches"
|
string += " <= no check matches"
|
||||||
fmtstrs.append(string)
|
fmtstrs.append(string)
|
||||||
|
@ -276,8 +316,8 @@ class TestFailure(object):
|
||||||
|
|
||||||
|
|
||||||
def perform_substitution(input_str, subs):
|
def perform_substitution(input_str, subs):
|
||||||
""" Perform the substitutions described by subs to str
|
"""Perform the substitutions described by subs to str
|
||||||
Return the substituted string.
|
Return the substituted string.
|
||||||
"""
|
"""
|
||||||
# Sort our substitutions into a list of tuples (key, value), descending by length.
|
# Sort our substitutions into a list of tuples (key, value), descending by length.
|
||||||
# It needs to be descending because we need to try longer substitutions first.
|
# It needs to be descending because we need to try longer substitutions first.
|
||||||
|
@ -368,11 +408,22 @@ class TestRun(object):
|
||||||
# If there's a mismatch or still lines or checkers, we have a failure.
|
# If there's a mismatch or still lines or checkers, we have a failure.
|
||||||
# Otherwise it's success.
|
# Otherwise it's success.
|
||||||
if mismatches:
|
if mismatches:
|
||||||
return TestFailure(mismatches[0][0], mismatches[0][1], self, diff=diff, lines=usedlines, checks=usedchecks)
|
return TestFailure(
|
||||||
|
mismatches[0][0],
|
||||||
|
mismatches[0][1],
|
||||||
|
self,
|
||||||
|
diff=diff,
|
||||||
|
lines=usedlines,
|
||||||
|
checks=usedchecks,
|
||||||
|
)
|
||||||
elif lineq:
|
elif lineq:
|
||||||
return TestFailure(lineq[-1], None, self, diff=diff, lines=usedlines, checks=usedchecks)
|
return TestFailure(
|
||||||
|
lineq[-1], None, self, diff=diff, lines=usedlines, checks=usedchecks
|
||||||
|
)
|
||||||
elif checkq:
|
elif checkq:
|
||||||
return TestFailure(None, checkq[-1], self, diff=diff, lines=usedlines, checks=usedchecks)
|
return TestFailure(
|
||||||
|
None, checkq[-1], self, diff=diff, lines=usedlines, checks=usedchecks
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# Success!
|
# Success!
|
||||||
return None
|
return None
|
||||||
|
@ -381,8 +432,8 @@ class TestRun(object):
|
||||||
""" Run the command. Return a TestFailure, or None. """
|
""" Run the command. Return a TestFailure, or None. """
|
||||||
|
|
||||||
def split_by_newlines(s):
|
def split_by_newlines(s):
|
||||||
""" Decode a string and split it by newlines only,
|
"""Decode a string and split it by newlines only,
|
||||||
retaining the newlines.
|
retaining the newlines.
|
||||||
"""
|
"""
|
||||||
return [s + "\n" for s in s.decode("utf-8").split("\n")]
|
return [s + "\n" for s in s.decode("utf-8").split("\n")]
|
||||||
|
|
||||||
|
@ -420,7 +471,7 @@ class TestRun(object):
|
||||||
# non-matching or unmatched stderr text, then annotate the outfail
|
# non-matching or unmatched stderr text, then annotate the outfail
|
||||||
# with it.
|
# with it.
|
||||||
if outfail and errfail and errfail.line:
|
if outfail and errfail and errfail.line:
|
||||||
outfail.error_annotation_lines = errlines[errfail.line.number - 1:]
|
outfail.error_annotation_lines = errlines[errfail.line.number - 1 :]
|
||||||
# Trim a trailing newline
|
# Trim a trailing newline
|
||||||
if outfail.error_annotation_lines[-1].text == "\n":
|
if outfail.error_annotation_lines[-1].text == "\n":
|
||||||
del outfail.error_annotation_lines[-1]
|
del outfail.error_annotation_lines[-1]
|
||||||
|
@ -528,8 +579,8 @@ def check_path(path, subs, config, failure_handler):
|
||||||
|
|
||||||
|
|
||||||
def parse_subs(subs):
|
def parse_subs(subs):
|
||||||
""" Given a list of input substitutions like 'foo=bar',
|
"""Given a list of input substitutions like 'foo=bar',
|
||||||
return a dictionary like {foo:bar}, or exit if invalid.
|
return a dictionary like {foo:bar}, or exit if invalid.
|
||||||
"""
|
"""
|
||||||
result = {}
|
result = {}
|
||||||
for sub in subs:
|
for sub in subs:
|
||||||
|
|
|
@ -79,7 +79,7 @@ def pexpect_error_type(err):
|
||||||
|
|
||||||
|
|
||||||
class Message(object):
|
class Message(object):
|
||||||
""" Some text either sent-to or received-from the spawned proc.
|
"""Some text either sent-to or received-from the spawned proc.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
dir: the message direction, either DIR_INPUT or DIR_OUTPUT
|
dir: the message direction, either DIR_INPUT or DIR_OUTPUT
|
||||||
|
@ -115,7 +115,7 @@ class Message(object):
|
||||||
|
|
||||||
|
|
||||||
class SpawnedProc(object):
|
class SpawnedProc(object):
|
||||||
""" A process, talking to our ptty. This wraps pexpect.spawn.
|
"""A process, talking to our ptty. This wraps pexpect.spawn.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
colorize: whether error messages should have ANSI color escapes
|
colorize: whether error messages should have ANSI color escapes
|
||||||
|
@ -127,15 +127,15 @@ class SpawnedProc(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name="fish", timeout=TIMEOUT_SECS, env=os.environ.copy()):
|
def __init__(self, name="fish", timeout=TIMEOUT_SECS, env=os.environ.copy()):
|
||||||
""" Construct from a name, timeout, and environment.
|
"""Construct from a name, timeout, and environment.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name: the name of the executable to launch, as a key into the
|
name: the name of the executable to launch, as a key into the
|
||||||
environment dictionary. By default this is 'fish' but may be
|
environment dictionary. By default this is 'fish' but may be
|
||||||
other executables.
|
other executables.
|
||||||
timeout: A timeout to pass to pexpect. This indicates how long to wait
|
timeout: A timeout to pass to pexpect. This indicates how long to wait
|
||||||
before giving up on some expected output.
|
before giving up on some expected output.
|
||||||
env: a string->string dictionary, describing the environment variables.
|
env: a string->string dictionary, describing the environment variables.
|
||||||
"""
|
"""
|
||||||
if name not in env:
|
if name not in env:
|
||||||
raise ValueError("'name' variable not found in environment" % name)
|
raise ValueError("'name' variable not found in environment" % name)
|
||||||
|
@ -155,8 +155,8 @@ class SpawnedProc(object):
|
||||||
return now - self.start_time
|
return now - self.start_time
|
||||||
|
|
||||||
def send(self, s):
|
def send(self, s):
|
||||||
""" Cover over pexpect.spawn.send().
|
"""Cover over pexpect.spawn.send().
|
||||||
Send the given string to the tty, returning the number of bytes written.
|
Send the given string to the tty, returning the number of bytes written.
|
||||||
"""
|
"""
|
||||||
res = self.spawn.send(s)
|
res = self.spawn.send(s)
|
||||||
when = self.time_since_first_message()
|
when = self.time_since_first_message()
|
||||||
|
@ -164,22 +164,22 @@ class SpawnedProc(object):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def sendline(self, s):
|
def sendline(self, s):
|
||||||
""" Cover over pexpect.spawn.sendline().
|
"""Cover over pexpect.spawn.sendline().
|
||||||
Send the given string + linesep to the tty, returning the number of bytes written.
|
Send the given string + linesep to the tty, returning the number of bytes written.
|
||||||
"""
|
"""
|
||||||
return self.send(s + os.linesep)
|
return self.send(s + os.linesep)
|
||||||
|
|
||||||
def expect_re(self, pat, pat_desc=None, unmatched=None, **kwargs):
|
def expect_re(self, pat, pat_desc=None, unmatched=None, **kwargs):
|
||||||
""" Cover over pexpect.spawn.expect().
|
"""Cover over pexpect.spawn.expect().
|
||||||
Consume all "new" output of self.spawn until the given pattern is matched, or
|
Consume all "new" output of self.spawn until the given pattern is matched, or
|
||||||
the timeout is reached.
|
the timeout is reached.
|
||||||
Note that output between the current position and the location of the match is
|
Note that output between the current position and the location of the match is
|
||||||
consumed as well.
|
consumed as well.
|
||||||
The pattern is typically a regular expression in string form, but may also be
|
The pattern is typically a regular expression in string form, but may also be
|
||||||
any of the types accepted by pexpect.spawn.expect().
|
any of the types accepted by pexpect.spawn.expect().
|
||||||
If the 'unmatched' parameter is given, it is printed as part of the error message
|
If the 'unmatched' parameter is given, it is printed as part of the error message
|
||||||
of any failure.
|
of any failure.
|
||||||
On failure, this prints an error and exits.
|
On failure, this prints an error and exits.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.spawn.expect(pat, **kwargs)
|
self.spawn.expect(pat, **kwargs)
|
||||||
|
@ -201,15 +201,15 @@ class SpawnedProc(object):
|
||||||
return self.expect_re(re.escape(s), **kwargs)
|
return self.expect_re(re.escape(s), **kwargs)
|
||||||
|
|
||||||
def expect_prompt(self, *args, increment=True, **kwargs):
|
def expect_prompt(self, *args, increment=True, **kwargs):
|
||||||
""" Convenience function which matches some text and then a prompt.
|
"""Convenience function which matches some text and then a prompt.
|
||||||
Match the given positional arguments as expect_re, and then look
|
Match the given positional arguments as expect_re, and then look
|
||||||
for a prompt.
|
for a prompt.
|
||||||
If increment is set, then this should be a new prompt and the prompt counter
|
If increment is set, then this should be a new prompt and the prompt counter
|
||||||
should be bumped; otherwise this is not a new prompt.
|
should be bumped; otherwise this is not a new prompt.
|
||||||
Returns None on success, and exits on failure.
|
Returns None on success, and exits on failure.
|
||||||
Example:
|
Example:
|
||||||
sp.sendline("echo hello world")
|
sp.sendline("echo hello world")
|
||||||
sp.expect_prompt("hello world")
|
sp.expect_prompt("hello world")
|
||||||
"""
|
"""
|
||||||
if args:
|
if args:
|
||||||
self.expect_re(*args, **kwargs)
|
self.expect_re(*args, **kwargs)
|
||||||
|
@ -221,10 +221,10 @@ class SpawnedProc(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
def report_exception_and_exit(self, pat, unmatched, err):
|
def report_exception_and_exit(self, pat, unmatched, err):
|
||||||
""" Things have gone badly.
|
"""Things have gone badly.
|
||||||
We have an exception 'err', some pexpect.ExceptionPexpect.
|
We have an exception 'err', some pexpect.ExceptionPexpect.
|
||||||
Report it to stdout, along with the offending call site.
|
Report it to stdout, along with the offending call site.
|
||||||
If 'unmatched' is set, print it to stdout.
|
If 'unmatched' is set, print it to stdout.
|
||||||
"""
|
"""
|
||||||
colors = self.colors()
|
colors = self.colors()
|
||||||
failtype = pexpect_error_type(err)
|
failtype = pexpect_error_type(err)
|
||||||
|
|
|
@ -114,8 +114,8 @@ pygments_style = None
|
||||||
# of _static/pygments.css
|
# of _static/pygments.css
|
||||||
html_theme_path = ["."]
|
html_theme_path = ["."]
|
||||||
html_theme = "python_docs_theme"
|
html_theme = "python_docs_theme"
|
||||||
#html_theme_path = ["./cloud_sptheme/themes"]
|
# html_theme_path = ["./cloud_sptheme/themes"]
|
||||||
#html_theme = "cloud"
|
# html_theme = "cloud"
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
# further. For a list of options available for each theme, see the
|
# further. For a list of options available for each theme, see the
|
||||||
|
@ -196,7 +196,13 @@ man_pages = [
|
||||||
("tutorial", "fish-tutorial", "fish-shell tutorial", [author], 1),
|
("tutorial", "fish-tutorial", "fish-shell tutorial", [author], 1),
|
||||||
("CHANGELOG", "fish-changelog", "fish-shell changelog", [author], 1),
|
("CHANGELOG", "fish-changelog", "fish-shell changelog", [author], 1),
|
||||||
("completions", "fish-completions", "Writing fish completions", [author], 1),
|
("completions", "fish-completions", "Writing fish completions", [author], 1),
|
||||||
("fish_for_bash_users", "fish-for-bash-users", "A quick fish primer for those coming from bash", [author], 1),
|
(
|
||||||
|
"fish_for_bash_users",
|
||||||
|
"fish-for-bash-users",
|
||||||
|
"A quick fish primer for those coming from bash",
|
||||||
|
[author],
|
||||||
|
1,
|
||||||
|
),
|
||||||
("faq", "fish-faq", "fish-shell faq", [author], 1),
|
("faq", "fish-faq", "fish-shell faq", [author], 1),
|
||||||
]
|
]
|
||||||
for path in sorted(glob.glob("cmds/*")):
|
for path in sorted(glob.glob("cmds/*")):
|
||||||
|
|
|
@ -62,9 +62,9 @@ ROLE_TO_TOKEN = {
|
||||||
|
|
||||||
|
|
||||||
def token_for_text_and_role(text, role):
|
def token_for_text_and_role(text, role):
|
||||||
""" Return the pygments token for some input text and a fish role
|
"""Return the pygments token for some input text and a fish role
|
||||||
|
|
||||||
This applies any special cases of ROLE_TO_TOKEN.
|
This applies any special cases of ROLE_TO_TOKEN.
|
||||||
"""
|
"""
|
||||||
if text.isspace():
|
if text.isspace():
|
||||||
# Here fish will return 'normal' or 'statement_terminator' for newline.
|
# Here fish will return 'normal' or 'statement_terminator' for newline.
|
||||||
|
@ -77,13 +77,13 @@ def token_for_text_and_role(text, role):
|
||||||
|
|
||||||
|
|
||||||
def tokenize_fish_command(code, offset):
|
def tokenize_fish_command(code, offset):
|
||||||
""" Tokenize some fish code, offset in a parent string, by shelling
|
"""Tokenize some fish code, offset in a parent string, by shelling
|
||||||
out to fish_indent.
|
out to fish_indent.
|
||||||
|
|
||||||
fish_indent will output a list of csv lines: start,end,type.
|
|
||||||
|
|
||||||
This function returns a list of (start, tok, value) tuples, as
|
fish_indent will output a list of csv lines: start,end,type.
|
||||||
Pygments expects.
|
|
||||||
|
This function returns a list of (start, tok, value) tuples, as
|
||||||
|
Pygments expects.
|
||||||
"""
|
"""
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.Popen(
|
||||||
["fish_indent", "--pygments"],
|
["fish_indent", "--pygments"],
|
||||||
|
@ -108,11 +108,11 @@ class FishIndentLexer(Lexer):
|
||||||
filenames = ["*.fish"]
|
filenames = ["*.fish"]
|
||||||
|
|
||||||
def get_tokens_unprocessed(self, input_text):
|
def get_tokens_unprocessed(self, input_text):
|
||||||
""" Return a list of (start, tok, value) tuples.
|
"""Return a list of (start, tok, value) tuples.
|
||||||
|
|
||||||
start is the index into the string
|
start is the index into the string
|
||||||
tok is the token type (as above)
|
tok is the token type (as above)
|
||||||
value is the string contents of the token
|
value is the string contents of the token
|
||||||
"""
|
"""
|
||||||
result = []
|
result = []
|
||||||
if not any(s.startswith(">") for s in input_text.splitlines()):
|
if not any(s.startswith(">") for s in input_text.splitlines()):
|
||||||
|
|
|
@ -3,10 +3,9 @@ import os
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
current_dir = os.path.abspath(os.path.dirname(__file__))
|
current_dir = os.path.abspath(os.path.dirname(__file__))
|
||||||
app.add_html_theme(
|
app.add_html_theme("python_docs_theme", current_dir)
|
||||||
'python_docs_theme', current_dir)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'parallel_read_safe': True,
|
"parallel_read_safe": True,
|
||||||
'parallel_write_safe': True,
|
"parallel_write_safe": True,
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,14 @@ function __fish_list_bluetoothctl_devices
|
||||||
# Output of `bluetoothctl devices`:
|
# Output of `bluetoothctl devices`:
|
||||||
# Device 01:23:34:56:89:AB Name1
|
# Device 01:23:34:56:89:AB Name1
|
||||||
# Device 01:23:34:56:89:AC Name2
|
# Device 01:23:34:56:89:AC Name2
|
||||||
bluetoothctl devices 2> /dev/null | string replace -r "^Device " "" | string replace " " \t
|
bluetoothctl devices 2>/dev/null | string replace -r "^Device " "" | string replace " " \t
|
||||||
end
|
end
|
||||||
|
|
||||||
function __fish_list_bluetoothctl_controllers
|
function __fish_list_bluetoothctl_controllers
|
||||||
# Output of `bluetoothctl list`:
|
# Output of `bluetoothctl list`:
|
||||||
# Controller 01:23:34:56:89:AB Name1 [default]
|
# Controller 01:23:34:56:89:AB Name1 [default]
|
||||||
# Controller 01:23:34:56:89:AC Name2
|
# Controller 01:23:34:56:89:AC Name2
|
||||||
bluetoothctl list 2> /dev/null | string replace -r "^Controller " "" | string replace " " \t
|
bluetoothctl list 2>/dev/null | string replace -r "^Controller " "" | string replace " " \t
|
||||||
end
|
end
|
||||||
|
|
||||||
complete -f -c bluetoothctl -n "not __fish_seen_subcommand_from $cmds" -a list -d "List available controllers"
|
complete -f -c bluetoothctl -n "not __fish_seen_subcommand_from $cmds" -a list -d "List available controllers"
|
||||||
|
|
|
@ -83,7 +83,7 @@ function __fish_ffmpeg_filters
|
||||||
end
|
end
|
||||||
|
|
||||||
ffmpeg -hide_banner -loglevel quiet -filters |
|
ffmpeg -hide_banner -loglevel quiet -filters |
|
||||||
string match -e -- '->' | # skip past the header
|
string match -e -- '->' | # skip past the header
|
||||||
string match -er $filter |
|
string match -er $filter |
|
||||||
string replace -rf '^ [TSC.]{3} +(\S+) +\S+->\S+ +(.*)' '$1\t$2'
|
string replace -rf '^ [TSC.]{3} +(\S+) +\S+->\S+ +(.*)' '$1\t$2'
|
||||||
end
|
end
|
||||||
|
@ -97,7 +97,7 @@ end
|
||||||
|
|
||||||
function __fish_ffmpeg_tunes
|
function __fish_ffmpeg_tunes
|
||||||
set -l cmdline (commandline)
|
set -l cmdline (commandline)
|
||||||
if string match -req '264'
|
if string match -req 264
|
||||||
printf "%s\n" film animation grain stillimage fastdecode zerolatency psnr ssim
|
printf "%s\n" film animation grain stillimage fastdecode zerolatency psnr ssim
|
||||||
end
|
end
|
||||||
if string match -req '265|hevc'
|
if string match -req '265|hevc'
|
||||||
|
@ -110,7 +110,7 @@ function __fish_ffmpeg_crfs
|
||||||
end
|
end
|
||||||
|
|
||||||
function __fish_ffmpeg_profile
|
function __fish_ffmpeg_profile
|
||||||
if string match -req '264'
|
if string match -req 264
|
||||||
printf "%s\n" baseline main high
|
printf "%s\n" baseline main high
|
||||||
end
|
end
|
||||||
if string match -req '265|hevc'
|
if string match -req '265|hevc'
|
||||||
|
@ -204,7 +204,7 @@ complete -c ffmpeg -s b -o "b:v" -d "Video bitrate"
|
||||||
complete -c ffmpeg -o dn -d "Disable data"
|
complete -c ffmpeg -o dn -d "Disable data"
|
||||||
# Advanced video options
|
# Advanced video options
|
||||||
complete -c ffmpeg -o pix_fmt
|
complete -c ffmpeg -o pix_fmt
|
||||||
__fish_ffmpeg_complete_regex "-pix_fmt" "(__fish_ffmpeg_pix_fmts)"
|
__fish_ffmpeg_complete_regex -pix_fmt "(__fish_ffmpeg_pix_fmts)"
|
||||||
|
|
||||||
# Audio options
|
# Audio options
|
||||||
complete -c ffmpeg -o aframes -d "Set the number of audio frames to output"
|
complete -c ffmpeg -o aframes -d "Set the number of audio frames to output"
|
||||||
|
@ -231,11 +231,11 @@ complete -c ffmpeg -o spre -d "Set the subtitle options to the indicated preset"
|
||||||
complete -c ffmpeg -o pre -o preset -d "Preset name"
|
complete -c ffmpeg -o pre -o preset -d "Preset name"
|
||||||
__fish_ffmpeg_complete_regex 'pre(set)?' "(__fish_ffmpeg_presets)"
|
__fish_ffmpeg_complete_regex 'pre(set)?' "(__fish_ffmpeg_presets)"
|
||||||
complete -c ffmpeg -o tune
|
complete -c ffmpeg -o tune
|
||||||
__fish_ffmpeg_complete_regex 'tune' "(__fish_ffmpeg_tunes)"
|
__fish_ffmpeg_complete_regex tune "(__fish_ffmpeg_tunes)"
|
||||||
complete -c ffmpeg -o crf -o q
|
complete -c ffmpeg -o crf -o q
|
||||||
__fish_ffmpeg_complete_regex 'crf|q' "(__fish_ffmpeg_crfs)"
|
__fish_ffmpeg_complete_regex 'crf|q' "(__fish_ffmpeg_crfs)"
|
||||||
complete -c ffmpeg -o profile
|
complete -c ffmpeg -o profile
|
||||||
__fish_ffmpeg_complete_regex 'profile' "(__fish_ffmpeg_profiles)"
|
__fish_ffmpeg_complete_regex profile "(__fish_ffmpeg_profiles)"
|
||||||
|
|
||||||
# Filters
|
# Filters
|
||||||
#
|
#
|
||||||
|
@ -281,11 +281,11 @@ function __fish_ffmpeg_concat_filter_args
|
||||||
end
|
end
|
||||||
|
|
||||||
function __fish_ffmpeg_complete_filter
|
function __fish_ffmpeg_complete_filter
|
||||||
set -l filter_type "all"
|
set -l filter_type all
|
||||||
if string match -rq -- '^-(vf(ilter)?|f(ilter)?:v)' (__fish_ffmpeg_last_arg)
|
if string match -rq -- '^-(vf(ilter)?|f(ilter)?:v)' (__fish_ffmpeg_last_arg)
|
||||||
set filter_type "video"
|
set filter_type video
|
||||||
else if string match -rq -- '^-(af(ilter)?|f(ilter)?:a' (__fish_ffmpeg_last_arg)
|
else if string match -rq -- '^-(af(ilter)?|f(ilter)?:a' (__fish_ffmpeg_last_arg)
|
||||||
set filter_type "audio"
|
set filter_type audio
|
||||||
end
|
end
|
||||||
|
|
||||||
# echo -e "\n **** $filter_type **** \n" > /dev/tty
|
# echo -e "\n **** $filter_type **** \n" > /dev/tty
|
||||||
|
|
|
@ -9,4 +9,4 @@ complete -f -c gapplication -n __fish_use_subcommand -a list-actions -d "List av
|
||||||
complete -f -c gapplication -n __fish_use_subcommand -a action -d "Activate an action"
|
complete -f -c gapplication -n __fish_use_subcommand -a action -d "Activate an action"
|
||||||
|
|
||||||
# Arguments of help command
|
# Arguments of help command
|
||||||
complete -f -c gapplication -n "__fish_seen_subcommand_from help" -a "help version list-apps launch list-actions action" -d "Command"
|
complete -f -c gapplication -n "__fish_seen_subcommand_from help" -a "help version list-apps launch list-actions action" -d Command
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
set -l supported_schemes admin afc afp archive burn cdda computer dav dav+sd davs davs+sd dns-sd file ftp ftpis ftps google-drive gphoto2 http https localtest mtp network nfs recent sftp smb ssh test trash
|
set -l supported_schemes admin afc afp archive burn cdda computer dav dav+sd davs davs+sd dns-sd file ftp ftpis ftps google-drive gphoto2 http https localtest mtp network nfs recent sftp smb ssh test trash
|
||||||
|
|
||||||
for scheme in $supported_schemes
|
for scheme in $supported_schemes
|
||||||
complete -c gio -n "__fish_seen_subcommand_from cat copy info list mkdir monitor mount move open rename remove save set trash tree" -a "$scheme": -d "Scheme"
|
complete -c gio -n "__fish_seen_subcommand_from cat copy info list mkdir monitor mount move open rename remove save set trash tree" -a "$scheme": -d Scheme
|
||||||
end
|
end
|
||||||
|
|
||||||
# Commands
|
# Commands
|
||||||
|
@ -28,7 +28,7 @@ complete -f -c gio -n __fish_use_subcommand -a trash -d "Move files to the trash
|
||||||
complete -f -c gio -n __fish_use_subcommand -a tree -d "Lists the contents of locations in a tree"
|
complete -f -c gio -n __fish_use_subcommand -a tree -d "Lists the contents of locations in a tree"
|
||||||
|
|
||||||
# Arguments of help command
|
# Arguments of help command
|
||||||
complete -f -c gio -n "__fish_seen_subcommand_from help" -a "version cat copy info list mime mkdir monitor mount move open rename remove save set trash tree" -d "Command"
|
complete -f -c gio -n "__fish_seen_subcommand_from help" -a "version cat copy info list mime mkdir monitor mount move open rename remove save set trash tree" -d Command
|
||||||
|
|
||||||
# Arguments of mime command
|
# Arguments of mime command
|
||||||
function __fish_gio_list_mimetypes
|
function __fish_gio_list_mimetypes
|
||||||
|
@ -76,13 +76,13 @@ complete -f -c gio -n "__fish_seen_subcommand_from monitor" -s m -l mounts -d "W
|
||||||
# Options of mount command
|
# Options of mount command
|
||||||
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s m -l mountable -d "Mount as mountable"
|
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s m -l mountable -d "Mount as mountable"
|
||||||
complete -x -c gio -n "__fish_seen_subcommand_from mount" -s d -l device -d "Mount volume"
|
complete -x -c gio -n "__fish_seen_subcommand_from mount" -s d -l device -d "Mount volume"
|
||||||
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s u -l unmount -d "Unmount"
|
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s u -l unmount -d Unmount
|
||||||
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s e -l eject -d "Eject"
|
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s e -l eject -d Eject
|
||||||
complete -x -c gio -n "__fish_seen_subcommand_from mount" -s t -l stop -d "Stop drive"
|
complete -x -c gio -n "__fish_seen_subcommand_from mount" -s t -l stop -d "Stop drive"
|
||||||
complete -x -c gio -n "__fish_seen_subcommand_from mount" -s s -l unmount-scheme -a "$supported_schemes" -d "Unmount all mounts with the given scheme"
|
complete -x -c gio -n "__fish_seen_subcommand_from mount" -s s -l unmount-scheme -a "$supported_schemes" -d "Unmount all mounts with the given scheme"
|
||||||
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s f -l force -d "Ignore outstanding file operations"
|
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s f -l force -d "Ignore outstanding file operations"
|
||||||
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s a -l anonymous -d "Use an anonymous user"
|
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s a -l anonymous -d "Use an anonymous user"
|
||||||
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s l -l list -d "List"
|
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s l -l list -d List
|
||||||
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s o -l monitor -d "Monitor events"
|
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s o -l monitor -d "Monitor events"
|
||||||
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s i -l detail -d "Show extra information"
|
complete -f -c gio -n "__fish_seen_subcommand_from mount" -s i -l detail -d "Show extra information"
|
||||||
complete -x -c gio -n "__fish_seen_subcommand_from mount" -l tcrypt-pim -d "The numeric PIM when unlocking a VeraCrypt volume"
|
complete -x -c gio -n "__fish_seen_subcommand_from mount" -l tcrypt-pim -d "The numeric PIM when unlocking a VeraCrypt volume"
|
||||||
|
|
|
@ -11,4 +11,4 @@ complete -f -c gresource -n "__fish_not_contain_opt section && __fish_use_subcom
|
||||||
complete -f -c gresource -n "__fish_not_contain_opt section && __fish_use_subcommand" -a help -d "Prints help"
|
complete -f -c gresource -n "__fish_not_contain_opt section && __fish_use_subcommand" -a help -d "Prints help"
|
||||||
|
|
||||||
# Arguments of help command
|
# Arguments of help command
|
||||||
complete -f -c gresource -n "__fish_seen_subcommand_from help" -a "list details extract sections help" -d "Command"
|
complete -f -c gresource -n "__fish_seen_subcommand_from help" -a "list details extract sections help" -d Command
|
||||||
|
|
|
@ -2,24 +2,24 @@
|
||||||
complete -c vips -s l -l list -d 'List objects'
|
complete -c vips -s l -l list -d 'List objects'
|
||||||
complete -c vips -s p -l plugin -d 'Load PLUGIN'
|
complete -c vips -s p -l plugin -d 'Load PLUGIN'
|
||||||
complete -c vips -s v -l version -d 'Print version'
|
complete -c vips -s v -l version -d 'Print version'
|
||||||
complete -c vips -l vips-concurrency -d 'Evaluate with N threads'
|
complete -c vips -l vips-concurrency -d 'Evaluate with N threads'
|
||||||
complete -c vips -l vips-progress -d 'Show progress feedback'
|
complete -c vips -l vips-progress -d 'Show progress feedback'
|
||||||
complete -c vips -l vips-leak -d 'Leak-check on exit'
|
complete -c vips -l vips-leak -d 'Leak-check on exit'
|
||||||
complete -c vips -l vips-profile -d 'Profile and dump timing on exit'
|
complete -c vips -l vips-profile -d 'Profile and dump timing on exit'
|
||||||
complete -c vips -l vips-disc-threshold -d 'Decompress images larger than N'
|
complete -c vips -l vips-disc-threshold -d 'Decompress images larger than N'
|
||||||
complete -c vips -l vips-novector -d 'Disable vectorised operations'
|
complete -c vips -l vips-novector -d 'Disable vectorised operations'
|
||||||
complete -c vips -l vips-cache-max -d 'Cache at most N operations'
|
complete -c vips -l vips-cache-max -d 'Cache at most N operations'
|
||||||
complete -c vips -l vips-cache-max-memory -d 'Cache at most N bytes in memory'
|
complete -c vips -l vips-cache-max-memory -d 'Cache at most N bytes in memory'
|
||||||
complete -c vips -l vips-cache-max-files -d 'Allow at most N open files'
|
complete -c vips -l vips-cache-max-files -d 'Allow at most N open files'
|
||||||
complete -c vips -l vips-cache-trace -d 'Trace operation cache'
|
complete -c vips -l vips-cache-trace -d 'Trace operation cache'
|
||||||
complete -c vips -l vips-cache-dump -d 'Dump operation cache on exit'
|
complete -c vips -l vips-cache-dump -d 'Dump operation cache on exit'
|
||||||
complete -c vips -l vips-version -d 'Print libvips version'
|
complete -c vips -l vips-version -d 'Print libvips version'
|
||||||
complete -c vips -l vips-config -d 'Print libvips config'
|
complete -c vips -l vips-config -d 'Print libvips config'
|
||||||
complete -c vips -l vips-pipe-read-limit -d 'Pipe read limit (bytes)'
|
complete -c vips -l vips-pipe-read-limit -d 'Pipe read limit (bytes)'
|
||||||
|
|
||||||
# Operations
|
# Operations
|
||||||
complete -c vips -n '__fish_is_first_token' -xa "(__fish_vips_ops)"
|
complete -c vips -n __fish_is_first_token -xa "(__fish_vips_ops)"
|
||||||
|
|
||||||
function __fish_vips_ops
|
function __fish_vips_ops
|
||||||
vips -l | string match -rv _base | string replace -rf '^\s*\S+ \((.+?)\), +(\S.*?)(?:\s*[,(].*)?$' '$1\t$2'
|
vips -l | string match -rv _base | string replace -rf '^\s*\S+ \((.+?)\), +(\S.*?)(?:\s*[,(].*)?$' '$1\t$2'
|
||||||
end
|
end
|
||||||
|
|
|
@ -135,7 +135,6 @@ function __fish_complete_mount_opts
|
||||||
barrier={0,1}\
|
barrier={0,1}\
|
||||||
user_xattr\
|
user_xattr\
|
||||||
acl\
|
acl\
|
||||||
|
|
||||||
set -l token (commandline -tc | string replace -r '^-o' -- '')
|
set -l token (commandline -tc | string replace -r '^-o' -- '')
|
||||||
set -l args (string split , -- $token)
|
set -l args (string split , -- $token)
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ function __fish_print_pipestatus --description "Print pipestatus for prompt"
|
||||||
set last_status_string " "$status_color$last_status
|
set last_status_string " "$status_color$last_status
|
||||||
end
|
end
|
||||||
printf "%s" $brace_sep_color $left_brace \
|
printf "%s" $brace_sep_color $left_brace \
|
||||||
$status_color $last_pipestatus_string \
|
$status_color $last_pipestatus_string \
|
||||||
$brace_sep_color $right_brace $last_status_string (set_color normal)
|
$brace_sep_color $right_brace $last_status_string (set_color normal)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,8 +8,8 @@ function __fish_print_zfs_snapshots -d "Lists ZFS snapshots"
|
||||||
set current_dataset (string replace -rf "([^@]+)@?.*" '$1' -- $current_token)
|
set current_dataset (string replace -rf "([^@]+)@?.*" '$1' -- $current_token)
|
||||||
set filtered_results (string match -ie -- $current_dataset $fast_results)
|
set filtered_results (string match -ie -- $current_dataset $fast_results)
|
||||||
if contains -- --force $argv ||
|
if contains -- --force $argv ||
|
||||||
string match -ieq @ -- $current_token ||
|
string match -ieq @ -- $current_token ||
|
||||||
not set -q filtered_results[2]
|
not set -q filtered_results[2]
|
||||||
|
|
||||||
# Ignore errors because the dataset specified could be non-existent
|
# Ignore errors because the dataset specified could be non-existent
|
||||||
zfs list -t snapshot -o name -H -d 1 $current_dataset 2>/dev/null
|
zfs list -t snapshot -o name -H -d 1 $current_dataset 2>/dev/null
|
||||||
|
|
|
@ -2,10 +2,10 @@ function __fish_status_to_signal --description "Print signal name from argument
|
||||||
for arg in $argv
|
for arg in $argv
|
||||||
if test $arg -gt 128
|
if test $arg -gt 128
|
||||||
set -l signals SIGHUP SIGINT SIGQUIT SIGILL SIGTRAP SIGABRT SIGBUS \
|
set -l signals SIGHUP SIGINT SIGQUIT SIGILL SIGTRAP SIGABRT SIGBUS \
|
||||||
SIGFPE SIGKILL SIGUSR1 SIGSEGV SIGUSR2 SIGPIPE SIGALRM \
|
SIGFPE SIGKILL SIGUSR1 SIGSEGV SIGUSR2 SIGPIPE SIGALRM \
|
||||||
SIGTERM SIGSTKFLT SIGCHLD SIGCONT SIGSTOP SIGTSTP \
|
SIGTERM SIGSTKFLT SIGCHLD SIGCONT SIGSTOP SIGTSTP \
|
||||||
SIGTTIN SIGTTOU SIGURG SIGXCPU SIGXFSZ SIGVTALRM \
|
SIGTTIN SIGTTOU SIGURG SIGXCPU SIGXFSZ SIGVTALRM \
|
||||||
SIGPROF SIGWINCH SIGIO SIGPWR SIGSYS
|
SIGPROF SIGWINCH SIGIO SIGPWR SIGSYS
|
||||||
set -l sigix (math $arg - 128)
|
set -l sigix (math $arg - 128)
|
||||||
if test $sigix -le (count $signals)
|
if test $sigix -le (count $signals)
|
||||||
echo $signals[$sigix]
|
echo $signals[$sigix]
|
||||||
|
|
|
@ -59,14 +59,14 @@ else if type -q pkgfile
|
||||||
end
|
end
|
||||||
else if type -q pacman
|
else if type -q pacman
|
||||||
function fish_command_not_found
|
function fish_command_not_found
|
||||||
set -l paths $argv[1]
|
set -l paths $argv[1]
|
||||||
# If we've not been given an absolute path, try $PATH as the starting point,
|
# If we've not been given an absolute path, try $PATH as the starting point,
|
||||||
# otherwise pacman will try *every path*, and e.g. bash-completion
|
# otherwise pacman will try *every path*, and e.g. bash-completion
|
||||||
# isn't helpful.
|
# isn't helpful.
|
||||||
string match -q '/*' -- $argv[1]; or set paths $PATH/$argv[1]
|
string match -q '/*' -- $argv[1]; or set paths $PATH/$argv[1]
|
||||||
# Pacman only prints the path, so we still need to print the error.
|
# Pacman only prints the path, so we still need to print the error.
|
||||||
__fish_default_command_not_found_handler $argv[1]
|
__fish_default_command_not_found_handler $argv[1]
|
||||||
pacman -F $paths
|
pacman -F $paths
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Use standard fish command not found handler otherwise
|
# Use standard fish command not found handler otherwise
|
||||||
|
|
|
@ -392,7 +392,9 @@ class Type2ManParser(ManParser):
|
||||||
options_section_regex = re.compile("\.SH OPTIONS(.*?)(\.SH|\Z)", re.DOTALL)
|
options_section_regex = re.compile("\.SH OPTIONS(.*?)(\.SH|\Z)", re.DOTALL)
|
||||||
options_section = re.search(options_section_regex, manpage).group(1)
|
options_section = re.search(options_section_regex, manpage).group(1)
|
||||||
|
|
||||||
options_parts_regex = re.compile("\.[IT]P( \d+(\.\d)?i?)?(.*?)\.([IT]P|UNINDENT|UN|SH)", re.DOTALL)
|
options_parts_regex = re.compile(
|
||||||
|
"\.[IT]P( \d+(\.\d)?i?)?(.*?)\.([IT]P|UNINDENT|UN|SH)", re.DOTALL
|
||||||
|
)
|
||||||
options_matched = re.search(options_parts_regex, options_section)
|
options_matched = re.search(options_parts_regex, options_section)
|
||||||
add_diagnostic("Command is %r" % CMDNAME)
|
add_diagnostic("Command is %r" % CMDNAME)
|
||||||
|
|
||||||
|
@ -421,6 +423,7 @@ class Type2ManParser(ManParser):
|
||||||
options_section = options_section[options_matched.end() - 3 :]
|
options_section = options_section[options_matched.end() - 3 :]
|
||||||
options_matched = re.search(options_parts_regex, options_section)
|
options_matched = re.search(options_parts_regex, options_section)
|
||||||
|
|
||||||
|
|
||||||
class Type3ManParser(ManParser):
|
class Type3ManParser(ManParser):
|
||||||
def is_my_type(self, manpage):
|
def is_my_type(self, manpage):
|
||||||
return compile_and_search("\.SH DESCRIPTION(.*?)", manpage) != None
|
return compile_and_search("\.SH DESCRIPTION(.*?)", manpage) != None
|
||||||
|
@ -467,7 +470,9 @@ class Type4ManParser(ManParser):
|
||||||
return compile_and_search("\.SH FUNCTION LETTERS(.*?)", manpage) != None
|
return compile_and_search("\.SH FUNCTION LETTERS(.*?)", manpage) != None
|
||||||
|
|
||||||
def parse_man_page(self, manpage):
|
def parse_man_page(self, manpage):
|
||||||
options_section_regex = re.compile("\.SH FUNCTION LETTERS(.*?)(\.SH|\Z)", re.DOTALL)
|
options_section_regex = re.compile(
|
||||||
|
"\.SH FUNCTION LETTERS(.*?)(\.SH|\Z)", re.DOTALL
|
||||||
|
)
|
||||||
options_section = re.search(options_section_regex, manpage).group(1)
|
options_section = re.search(options_section_regex, manpage).group(1)
|
||||||
|
|
||||||
options_parts_regex = re.compile("\.TP(.*?)\.TP", re.DOTALL)
|
options_parts_regex = re.compile("\.TP(.*?)\.TP", re.DOTALL)
|
||||||
|
@ -502,9 +507,15 @@ class Type4ManParser(ManParser):
|
||||||
options_section = options_section[options_matched.end() - 3 :]
|
options_section = options_section[options_matched.end() - 3 :]
|
||||||
options_matched = re.search(options_parts_regex, options_section)
|
options_matched = re.search(options_parts_regex, options_section)
|
||||||
|
|
||||||
|
|
||||||
class TypeScdocManParser(ManParser):
|
class TypeScdocManParser(ManParser):
|
||||||
def is_my_type(self, manpage):
|
def is_my_type(self, manpage):
|
||||||
return compile_and_search(r"\.(\\)(\") Generated by scdoc(.*?)\.SH OPTIONS(.*?)", manpage) != None
|
return (
|
||||||
|
compile_and_search(
|
||||||
|
r"\.(\\)(\") Generated by scdoc(.*?)\.SH OPTIONS(.*?)", manpage
|
||||||
|
)
|
||||||
|
!= None
|
||||||
|
)
|
||||||
|
|
||||||
def parse_man_page(self, manpage):
|
def parse_man_page(self, manpage):
|
||||||
options_section_regex = re.compile("\.SH OPTIONS(.*?)\.SH", re.DOTALL)
|
options_section_regex = re.compile("\.SH OPTIONS(.*?)\.SH", re.DOTALL)
|
||||||
|
@ -524,7 +535,7 @@ class TypeScdocManParser(ManParser):
|
||||||
while options_matched != None:
|
while options_matched != None:
|
||||||
# Get first option and move options_section
|
# Get first option and move options_section
|
||||||
option = options_matched.group(1)
|
option = options_matched.group(1)
|
||||||
options_section = options_section[options_matched.end()::]
|
options_section = options_section[options_matched.end() : :]
|
||||||
options_matched = re.match(options_parts_regex, options_section)
|
options_matched = re.match(options_parts_regex, options_section)
|
||||||
|
|
||||||
option = remove_groff_formatting(option)
|
option = remove_groff_formatting(option)
|
||||||
|
@ -540,7 +551,7 @@ class TypeScdocManParser(ManParser):
|
||||||
if len(option_clean) < 2:
|
if len(option_clean) < 2:
|
||||||
add_diagnostic("Unable to split option from description")
|
add_diagnostic("Unable to split option from description")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Name and description, others lines are ignored
|
# Name and description, others lines are ignored
|
||||||
option_name = option_clean[0]
|
option_name = option_clean[0]
|
||||||
option_description = option_clean[1]
|
option_description = option_clean[1]
|
||||||
|
@ -758,6 +769,7 @@ def cleanup_autogenerated_file(path):
|
||||||
except (OSError, IOError):
|
except (OSError, IOError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def parse_manpage_at_path(manpage_path, output_directory):
|
def parse_manpage_at_path(manpage_path, output_directory):
|
||||||
# Return if CMDNAME is in 'ignoredcommands'
|
# Return if CMDNAME is in 'ignoredcommands'
|
||||||
ignoredcommands = [
|
ignoredcommands = [
|
||||||
|
@ -862,14 +874,15 @@ def parse_manpage_at_path(manpage_path, output_directory):
|
||||||
output_file = codecs.open(fullpath, "w", encoding="utf-8")
|
output_file = codecs.open(fullpath, "w", encoding="utf-8")
|
||||||
except IOError as err:
|
except IOError as err:
|
||||||
add_diagnostic(
|
add_diagnostic(
|
||||||
"Unable to open file '%s': error(%d): %s"
|
"Unable to open file '%s': error(%d): %s"
|
||||||
% (fullpath, err.errno, err.strerror)
|
% (fullpath, err.errno, err.strerror)
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Output the magic word Autogenerated so we can tell if we can overwrite this
|
# Output the magic word Autogenerated so we can tell if we can overwrite this
|
||||||
built_command_output.insert(0, "# " + CMDNAME +
|
built_command_output.insert(
|
||||||
"\n# Autogenerated from man page " + manpage_path)
|
0, "# " + CMDNAME + "\n# Autogenerated from man page " + manpage_path
|
||||||
|
)
|
||||||
# built_command_output.insert(2, "# using " + parser.__class__.__name__) # XXX MISATTRIBUTES THE CULPABLE PARSER! Was really using Type2 but reporting TypeDeroffManParser
|
# built_command_output.insert(2, "# using " + parser.__class__.__name__) # XXX MISATTRIBUTES THE CULPABLE PARSER! Was really using Type2 but reporting TypeDeroffManParser
|
||||||
|
|
||||||
for line in built_command_output:
|
for line in built_command_output:
|
||||||
|
@ -1021,7 +1034,10 @@ if __name__ == "__main__":
|
||||||
action="append",
|
action="append",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-d", "--directory", type=str, help="The directory to save the completions in",
|
"-d",
|
||||||
|
"--directory",
|
||||||
|
type=str,
|
||||||
|
help="The directory to save the completions in",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-k",
|
"-k",
|
||||||
|
@ -1030,13 +1046,22 @@ if __name__ == "__main__":
|
||||||
action="store_true",
|
action="store_true",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-m", "--manpath", help="Whether to use manpath", action="store_true",
|
"-m",
|
||||||
|
"--manpath",
|
||||||
|
help="Whether to use manpath",
|
||||||
|
action="store_true",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-p", "--progress", help="Whether to show progress", action="store_true",
|
"-p",
|
||||||
|
"--progress",
|
||||||
|
help="Whether to show progress",
|
||||||
|
action="store_true",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-s", "--stdout", help="Write the completions to stdout", action="store_true",
|
"-s",
|
||||||
|
"--stdout",
|
||||||
|
help="Write the completions to stdout",
|
||||||
|
action="store_true",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-v",
|
"-v",
|
||||||
|
@ -1046,7 +1071,10 @@ if __name__ == "__main__":
|
||||||
help="The level of debug output to show",
|
help="The level of debug output to show",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-z", "--deroff-only", help="Whether to just deroff", action="store_true",
|
"-z",
|
||||||
|
"--deroff-only",
|
||||||
|
help="Whether to just deroff",
|
||||||
|
action="store_true",
|
||||||
)
|
)
|
||||||
parser.add_argument("file_paths", type=str, nargs="*")
|
parser.add_argument("file_paths", type=str, nargs="*")
|
||||||
|
|
||||||
|
|
|
@ -165,8 +165,7 @@ def better_color(c1, c2):
|
||||||
|
|
||||||
|
|
||||||
def parse_color(color_str):
|
def parse_color(color_str):
|
||||||
""" A basic function to parse a color string, for example, 'red' '--bold'.
|
"""A basic function to parse a color string, for example, 'red' '--bold'."""
|
||||||
"""
|
|
||||||
comps = color_str.split(" ")
|
comps = color_str.split(" ")
|
||||||
color = "normal"
|
color = "normal"
|
||||||
background_color = ""
|
background_color = ""
|
||||||
|
@ -1174,7 +1173,9 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# If the platform doesn't support multiprocessing, we just do it one at a time.
|
# If the platform doesn't support multiprocessing, we just do it one at a time.
|
||||||
# This happens e.g. on Termux.
|
# This happens e.g. on Termux.
|
||||||
print("Platform doesn't support multiprocessing, running one at a time. This may take a while.")
|
print(
|
||||||
|
"Platform doesn't support multiprocessing, running one at a time. This may take a while."
|
||||||
|
)
|
||||||
result.append(self.do_get_current_prompt())
|
result.append(self.do_get_current_prompt())
|
||||||
result.extend([self.read_one_sample_prompt(path) for path in paths])
|
result.extend([self.read_one_sample_prompt(path) for path in paths])
|
||||||
return result
|
return result
|
||||||
|
@ -1499,6 +1500,7 @@ print(
|
||||||
)
|
)
|
||||||
print("%sHit ENTER to stop.%s" % (esc["bold"], esc["exit_attribute_mode"]))
|
print("%sHit ENTER to stop.%s" % (esc["bold"], esc["exit_attribute_mode"]))
|
||||||
|
|
||||||
|
|
||||||
def runThing():
|
def runThing():
|
||||||
if isMacOS10_12_5_OrLater():
|
if isMacOS10_12_5_OrLater():
|
||||||
subprocess.check_call(["open", fileurl])
|
subprocess.check_call(["open", fileurl])
|
||||||
|
@ -1509,6 +1511,7 @@ def runThing():
|
||||||
else:
|
else:
|
||||||
webbrowser.open(fileurl)
|
webbrowser.open(fileurl)
|
||||||
|
|
||||||
|
|
||||||
# Some browsers still block webbrowser.open if they haven't been opened before,
|
# Some browsers still block webbrowser.open if they haven't been opened before,
|
||||||
# so we just spawn it in a thread.
|
# so we just spawn it in a thread.
|
||||||
thread = threading.Thread(target=runThing)
|
thread = threading.Thread(target=runThing)
|
||||||
|
|
|
@ -197,7 +197,7 @@ void accept_field_visitor(FieldVisitor &v, bool /*reverse*/, Field &field) {
|
||||||
|
|
||||||
// Call visit_field on visitor \p v, for the field \p field and also \p rest.
|
// Call visit_field on visitor \p v, for the field \p field and also \p rest.
|
||||||
template <typename FieldVisitor, typename Field, typename... Rest>
|
template <typename FieldVisitor, typename Field, typename... Rest>
|
||||||
void accept_field_visitor(FieldVisitor &v, bool reverse, Field &field, Rest &... rest) {
|
void accept_field_visitor(FieldVisitor &v, bool reverse, Field &field, Rest &...rest) {
|
||||||
if (!reverse) visit_1_field(v, field);
|
if (!reverse) visit_1_field(v, field);
|
||||||
accept_field_visitor<FieldVisitor, Rest...>(v, reverse, rest...);
|
accept_field_visitor<FieldVisitor, Rest...>(v, reverse, rest...);
|
||||||
if (reverse) visit_1_field(v, field);
|
if (reverse) visit_1_field(v, field);
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
//
|
//
|
||||||
// 1). Create a function in builtin.c with the following signature:
|
// 1). Create a function in builtin.c with the following signature:
|
||||||
//
|
//
|
||||||
// <tt>static maybe_t<int> builtin_NAME(parser_t &parser, io_streams_t &streams, wchar_t **argv)</tt>
|
// <tt>static maybe_t<int> builtin_NAME(parser_t &parser, io_streams_t &streams, wchar_t
|
||||||
|
// **argv)</tt>
|
||||||
//
|
//
|
||||||
// where NAME is the name of the builtin, and args is a zero-terminated list of arguments.
|
// where NAME is the name of the builtin, and args is a zero-terminated list of arguments.
|
||||||
//
|
//
|
||||||
|
@ -257,7 +258,8 @@ static maybe_t<int> builtin_count(parser_t &parser, io_streams_t &streams, wchar
|
||||||
|
|
||||||
/// This function handles both the 'continue' and the 'break' builtins that are used for loop
|
/// This function handles both the 'continue' and the 'break' builtins that are used for loop
|
||||||
/// control.
|
/// control.
|
||||||
static maybe_t<int> builtin_break_continue(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
static maybe_t<int> builtin_break_continue(parser_t &parser, io_streams_t &streams,
|
||||||
|
wchar_t **argv) {
|
||||||
int is_break = (std::wcscmp(argv[0], L"break") == 0);
|
int is_break = (std::wcscmp(argv[0], L"break") == 0);
|
||||||
int argc = builtin_count_args(argv);
|
int argc = builtin_count_args(argv);
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,10 @@ struct command_cmd_opts_t {
|
||||||
bool all_paths = false;
|
bool all_paths = false;
|
||||||
};
|
};
|
||||||
static const wchar_t *const short_options = L":ahqsv";
|
static const wchar_t *const short_options = L":ahqsv";
|
||||||
static const struct woption long_options[] = {{L"help", no_argument, nullptr, 'h'},
|
static const struct woption long_options[] = {
|
||||||
{L"all", no_argument, nullptr, 'a'},
|
{L"help", no_argument, nullptr, 'h'}, {L"all", no_argument, nullptr, 'a'},
|
||||||
{L"quiet", no_argument, nullptr, 'q'},
|
{L"quiet", no_argument, nullptr, 'q'}, {L"query", no_argument, nullptr, 'q'},
|
||||||
{L"query", no_argument, nullptr, 'q'},
|
{L"search", no_argument, nullptr, 's'}, {nullptr, 0, nullptr, 0}};
|
||||||
{L"search", no_argument, nullptr, 's'},
|
|
||||||
{nullptr, 0, nullptr, 0}};
|
|
||||||
|
|
||||||
static int parse_cmd_opts(command_cmd_opts_t &opts, int *optind, int argc, wchar_t **argv,
|
static int parse_cmd_opts(command_cmd_opts_t &opts, int *optind, int argc, wchar_t **argv,
|
||||||
parser_t &parser, io_streams_t &streams) {
|
parser_t &parser, io_streams_t &streams) {
|
||||||
|
|
|
@ -79,7 +79,8 @@ maybe_t<int> builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv)
|
||||||
streams.err.append_format(_(L"%ls: No suitable job: %d\n"), cmd, pid);
|
streams.err.append_format(_(L"%ls: No suitable job: %d\n"), cmd, pid);
|
||||||
job = nullptr;
|
job = nullptr;
|
||||||
} else if (!job->wants_job_control()) {
|
} else if (!job->wants_job_control()) {
|
||||||
streams.err.append_format(_(L"%ls: Can't put job %d, '%ls' to foreground because it is not under job control\n"),
|
streams.err.append_format(_(L"%ls: Can't put job %d, '%ls' to foreground because "
|
||||||
|
L"it is not under job control\n"),
|
||||||
cmd, pid, job->command_wcstr());
|
cmd, pid, job->command_wcstr());
|
||||||
job = nullptr;
|
job = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,8 +199,9 @@ static int validate_function_name(int argc, const wchar_t *const *argv, wcstring
|
||||||
|
|
||||||
/// Define a function. Calls into `function.cpp` to perform the heavy lifting of defining a
|
/// Define a function. Calls into `function.cpp` to perform the heavy lifting of defining a
|
||||||
/// function.
|
/// function.
|
||||||
maybe_t<int> builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_list_t &c_args,
|
maybe_t<int> builtin_function(parser_t &parser, io_streams_t &streams,
|
||||||
const parsed_source_ref_t &source, const ast::block_statement_t &func_node) {
|
const wcstring_list_t &c_args, const parsed_source_ref_t &source,
|
||||||
|
const ast::block_statement_t &func_node) {
|
||||||
assert(source && "Missing source in builtin_function");
|
assert(source && "Missing source in builtin_function");
|
||||||
// The wgetopt function expects 'function' as the first argument. Make a new wcstring_list with
|
// The wgetopt function expects 'function' as the first argument. Make a new wcstring_list with
|
||||||
// that property. This is needed because this builtin has a different signature than the other
|
// that property. This is needed because this builtin has a different signature than the other
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace ast {
|
||||||
struct block_statement_t;
|
struct block_statement_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
maybe_t<int> builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_list_t &c_args,
|
maybe_t<int> builtin_function(parser_t &parser, io_streams_t &streams,
|
||||||
const parsed_source_ref_t &source, const ast::block_statement_t &func_node);
|
const wcstring_list_t &c_args, const parsed_source_ref_t &source,
|
||||||
|
const ast::block_statement_t &func_node);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -286,7 +286,8 @@ maybe_t<int> builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t
|
||||||
wcstring new_func;
|
wcstring new_func;
|
||||||
|
|
||||||
if (argc - optind != 2) {
|
if (argc - optind != 2) {
|
||||||
streams.err.append_format(_(L"%ls: Expected exactly two names (current function name, and new function name)\n"),
|
streams.err.append_format(_(L"%ls: Expected exactly two names (current function name, "
|
||||||
|
L"and new function name)\n"),
|
||||||
cmd);
|
cmd);
|
||||||
builtin_print_error_trailer(parser, streams.err, cmd);
|
builtin_print_error_trailer(parser, streams.err, cmd);
|
||||||
return STATUS_INVALID_ARGS;
|
return STATUS_INVALID_ARGS;
|
||||||
|
|
|
@ -129,14 +129,11 @@ maybe_t<int> builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **arg
|
||||||
bool print_last = false;
|
bool print_last = false;
|
||||||
|
|
||||||
static const wchar_t *const short_options = L":cghlpq";
|
static const wchar_t *const short_options = L":cghlpq";
|
||||||
static const struct woption long_options[] = {{L"command", no_argument, nullptr, 'c'},
|
static const struct woption long_options[] = {
|
||||||
{L"group", no_argument, nullptr, 'g'},
|
{L"command", no_argument, nullptr, 'c'}, {L"group", no_argument, nullptr, 'g'},
|
||||||
{L"help", no_argument, nullptr, 'h'},
|
{L"help", no_argument, nullptr, 'h'}, {L"last", no_argument, nullptr, 'l'},
|
||||||
{L"last", no_argument, nullptr, 'l'},
|
{L"pid", no_argument, nullptr, 'p'}, {L"quiet", no_argument, nullptr, 'q'},
|
||||||
{L"pid", no_argument, nullptr, 'p'},
|
{L"query", no_argument, nullptr, 'q'}, {nullptr, 0, nullptr, 0}};
|
||||||
{L"quiet", no_argument, nullptr, 'q'},
|
|
||||||
{L"query", no_argument, nullptr, 'q'},
|
|
||||||
{nullptr, 0, nullptr, 0}};
|
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
wgetopter_t w;
|
wgetopter_t w;
|
||||||
|
|
|
@ -489,8 +489,9 @@ maybe_t<int> builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **arg
|
||||||
int stream_stdin_is_a_tty = isatty(streams.stdin_fd);
|
int stream_stdin_is_a_tty = isatty(streams.stdin_fd);
|
||||||
if (stream_stdin_is_a_tty && !opts.split_null) {
|
if (stream_stdin_is_a_tty && !opts.split_null) {
|
||||||
// Read interactively using reader_readline(). This does not support splitting on null.
|
// Read interactively using reader_readline(). This does not support splitting on null.
|
||||||
exit_res = read_interactive(parser, buff, opts.nchars, opts.shell, opts.silent,
|
exit_res =
|
||||||
opts.prompt, opts.right_prompt, opts.commandline, streams.stdin_fd);
|
read_interactive(parser, buff, opts.nchars, opts.shell, opts.silent, opts.prompt,
|
||||||
|
opts.right_prompt, opts.commandline, streams.stdin_fd);
|
||||||
} else if (!opts.nchars && !stream_stdin_is_a_tty &&
|
} else if (!opts.nchars && !stream_stdin_is_a_tty &&
|
||||||
lseek(streams.stdin_fd, 0, SEEK_CUR) != -1) {
|
lseek(streams.stdin_fd, 0, SEEK_CUR) != -1) {
|
||||||
exit_res = read_in_chunks(streams.stdin_fd, buff, opts.split_null);
|
exit_res = read_in_chunks(streams.stdin_fd, buff, opts.split_null);
|
||||||
|
|
|
@ -91,7 +91,8 @@ maybe_t<int> builtin_realpath(parser_t &parser, io_streams_t &streams, wchar_t *
|
||||||
std::strerror(errno));
|
std::strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
// Who knows. Probably a bug in our wrealpath() implementation.
|
// Who knows. Probably a bug in our wrealpath() implementation.
|
||||||
streams.err.append_format(_(L"builtin %ls: Invalid path: %ls\n"), cmd, argv[optind]);
|
streams.err.append_format(_(L"builtin %ls: Invalid path: %ls\n"), cmd,
|
||||||
|
argv[optind]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_CMD_ERROR;
|
return STATUS_CMD_ERROR;
|
||||||
|
|
|
@ -643,7 +643,8 @@ static int builtin_set_erase(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
|
||||||
parser_t &parser, io_streams_t &streams) {
|
parser_t &parser, io_streams_t &streams) {
|
||||||
int ret = STATUS_CMD_OK;
|
int ret = STATUS_CMD_OK;
|
||||||
for (int i = 0; i < argc; i++) {
|
for (int i = 0; i < argc; i++) {
|
||||||
int scope = compute_scope(opts); // calculate the variable scope based on the provided options
|
int scope =
|
||||||
|
compute_scope(opts); // calculate the variable scope based on the provided options
|
||||||
wchar_t *dest = argv[i];
|
wchar_t *dest = argv[i];
|
||||||
|
|
||||||
std::vector<long> indexes;
|
std::vector<long> indexes;
|
||||||
|
@ -675,7 +676,8 @@ static int builtin_set_erase(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
|
||||||
wcstring_list_t result;
|
wcstring_list_t result;
|
||||||
dest_var->to_list(result);
|
dest_var->to_list(result);
|
||||||
erase_values(result, indexes);
|
erase_values(result, indexes);
|
||||||
retval = env_set_reporting_errors(cmd, dest, scope, result, streams, parser.vars(), &evts);
|
retval =
|
||||||
|
env_set_reporting_errors(cmd, dest, scope, result, streams, parser.vars(), &evts);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fire any events.
|
// Fire any events.
|
||||||
|
|
|
@ -33,7 +33,8 @@
|
||||||
|
|
||||||
class parser_t;
|
class parser_t;
|
||||||
|
|
||||||
static void print_modifiers(outputter_t &outp, bool bold, bool underline, bool italics, bool dim, bool reverse, rgb_color_t bg) {
|
static void print_modifiers(outputter_t &outp, bool bold, bool underline, bool italics, bool dim,
|
||||||
|
bool reverse, rgb_color_t bg) {
|
||||||
if (bold && enter_bold_mode) {
|
if (bold && enter_bold_mode) {
|
||||||
// These casts are needed to work with different curses implementations.
|
// These casts are needed to work with different curses implementations.
|
||||||
writembs_nofail(outp, tparm(const_cast<char *>(enter_bold_mode)));
|
writembs_nofail(outp, tparm(const_cast<char *>(enter_bold_mode)));
|
||||||
|
@ -59,11 +60,10 @@ static void print_modifiers(outputter_t &outp, bool bold, bool underline, bool i
|
||||||
if (!bg.is_none() && bg.is_normal()) {
|
if (!bg.is_none() && bg.is_normal()) {
|
||||||
writembs_nofail(outp, tparm(const_cast<char *>(exit_attribute_mode)));
|
writembs_nofail(outp, tparm(const_cast<char *>(exit_attribute_mode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_colors(io_streams_t &streams, bool bold, bool underline, bool italics, bool dim,
|
||||||
static void print_colors(io_streams_t &streams, bool bold, bool underline, bool italics, bool dim, bool reverse, rgb_color_t bg) {
|
bool reverse, rgb_color_t bg) {
|
||||||
outputter_t outp;
|
outputter_t outp;
|
||||||
for (const auto &color_name : rgb_color_t::named_color_names()) {
|
for (const auto &color_name : rgb_color_t::named_color_names()) {
|
||||||
if (!streams.out_is_redirected && isatty(STDOUT_FILENO)) {
|
if (!streams.out_is_redirected && isatty(STDOUT_FILENO)) {
|
||||||
|
@ -134,7 +134,8 @@ maybe_t<int> builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t
|
||||||
}
|
}
|
||||||
|
|
||||||
const wchar_t *bgcolor = nullptr;
|
const wchar_t *bgcolor = nullptr;
|
||||||
bool bold = false, underline = false, italics = false, dim = false, reverse = false, print = false;
|
bool bold = false, underline = false, italics = false, dim = false, reverse = false,
|
||||||
|
print = false;
|
||||||
|
|
||||||
// Parse options to obtain the requested operation and the modifiers.
|
// Parse options to obtain the requested operation and the modifiers.
|
||||||
int opt;
|
int opt;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "builtin_type.h"
|
#include "builtin_type.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
|
|
|
@ -206,10 +206,11 @@ bool is_windows_subsystem_for_linux() {
|
||||||
int status = -1;
|
int status = -1;
|
||||||
if (info.dli_sname[0] == '_')
|
if (info.dli_sname[0] == '_')
|
||||||
demangled = abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, &status);
|
demangled = abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, &status);
|
||||||
swprintf(
|
swprintf(text, sizeof(text) / sizeof(wchar_t), L"%-3d %s + %td", i - skip_levels,
|
||||||
text, sizeof(text) / sizeof(wchar_t), L"%-3d %s + %td", i - skip_levels,
|
status == 0 ? demangled
|
||||||
status == 0 ? demangled : info.dli_sname == nullptr ? symbols[i] : info.dli_sname,
|
: info.dli_sname == nullptr ? symbols[i]
|
||||||
static_cast<char *>(callstack[i]) - static_cast<char *>(info.dli_saddr));
|
: info.dli_sname,
|
||||||
|
static_cast<char *>(callstack[i]) - static_cast<char *>(info.dli_saddr));
|
||||||
free(demangled);
|
free(demangled);
|
||||||
} else {
|
} else {
|
||||||
swprintf(text, sizeof(text) / sizeof(wchar_t), L"%-3d %s", i - skip_levels, symbols[i]);
|
swprintf(text, sizeof(text) / sizeof(wchar_t), L"%-3d %s", i - skip_levels, symbols[i]);
|
||||||
|
@ -227,7 +228,7 @@ bool is_windows_subsystem_for_linux() {
|
||||||
debug_shared(msg_level, L"Backtrace:\n" + join_strings(bt, L'\n') + L'\n');
|
debug_shared(msg_level, L"Backtrace:\n" + join_strings(bt, L'\n') + L'\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // HAVE_BACKTRACE_SYMBOLS
|
#else // HAVE_BACKTRACE_SYMBOLS
|
||||||
|
|
||||||
[[gnu::noinline]] void show_stackframe(const wchar_t msg_level, int, int) {
|
[[gnu::noinline]] void show_stackframe(const wchar_t msg_level, int, int) {
|
||||||
debug_shared(msg_level, L"Sorry, but your system does not support backtraces");
|
debug_shared(msg_level, L"Sorry, but your system does not support backtraces");
|
||||||
|
|
|
@ -579,7 +579,7 @@ using std::make_unique;
|
||||||
#else
|
#else
|
||||||
/// make_unique implementation
|
/// make_unique implementation
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
std::unique_ptr<T> make_unique(Args &&... args) {
|
std::unique_ptr<T> make_unique(Args &&...args) {
|
||||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1327,7 +1327,7 @@ using test_list_t = std::vector<test_t>;
|
||||||
|
|
||||||
// Add a new test to a test list based on a series of ints and texts.
|
// Add a new test to a test list based on a series of ints and texts.
|
||||||
template <typename... Types>
|
template <typename... Types>
|
||||||
void add_test(test_list_t *v, const Types &... types) {
|
void add_test(test_list_t *v, const Types &...types) {
|
||||||
segment_t segments[] = {types...};
|
segment_t segments[] = {types...};
|
||||||
v->emplace_back(std::begin(segments), std::end(segments));
|
v->emplace_back(std::begin(segments), std::end(segments));
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,7 @@ class logger_t {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename... Ts>
|
template <typename T, typename... Ts>
|
||||||
void log_args_impl(const T &arg, const Ts &... rest) {
|
void log_args_impl(const T &arg, const Ts &...rest) {
|
||||||
log1(arg);
|
log1(arg);
|
||||||
log1(' ');
|
log1(' ');
|
||||||
log_args_impl<Ts...>(rest...);
|
log_args_impl<Ts...>(rest...);
|
||||||
|
@ -151,7 +151,7 @@ class logger_t {
|
||||||
logger_t();
|
logger_t();
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void log_args(const category_t &cat, const Args &... args) {
|
void log_args(const category_t &cat, const Args &...args) {
|
||||||
log1(cat.name);
|
log1(cat.name);
|
||||||
log1(": ");
|
log1(": ");
|
||||||
log_args_impl(args...);
|
log_args_impl(args...);
|
||||||
|
|
|
@ -79,7 +79,7 @@ class latch_t : detail::fixed_t {
|
||||||
void operator=(T &&value) { *this = make_unique<T>(std::move(value)); }
|
void operator=(T &&value) { *this = make_unique<T>(std::move(value)); }
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void emplace(Args &&... args) {
|
void emplace(Args &&...args) {
|
||||||
*this = make_unique<T>(std::forward<Args>(args)...);
|
*this = make_unique<T>(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1116,8 +1116,8 @@ static bool should_import_bash_history_line(const wcstring &line) {
|
||||||
if (line.find(L"]]") != std::string::npos) return false;
|
if (line.find(L"]]") != std::string::npos) return false;
|
||||||
if (line.find(L"((") != std::string::npos) return false;
|
if (line.find(L"((") != std::string::npos) return false;
|
||||||
if (line.find(L"))") != std::string::npos) return false;
|
if (line.find(L"))") != std::string::npos) return false;
|
||||||
// Skip lines with literal tabs since we don't handle them well and we don't know what they mean.
|
// Skip lines with literal tabs since we don't handle them well and we don't know what they
|
||||||
// It could just be whitespace or it's actually passed somewhere (like e.g. `sed`).
|
// mean. It could just be whitespace or it's actually passed somewhere (like e.g. `sed`).
|
||||||
if (line.find(L'\t') != std::string::npos) return false;
|
if (line.find(L'\t') != std::string::npos) return false;
|
||||||
|
|
||||||
// Skip lines that end with a backslash. We do not handle multiline commands from bash history.
|
// Skip lines that end with a backslash. We do not handle multiline commands from bash history.
|
||||||
|
|
|
@ -194,8 +194,9 @@ class input_event_queue_t {
|
||||||
char_event_t readb();
|
char_event_t readb();
|
||||||
|
|
||||||
int in_{0};
|
int in_{0};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
input_event_queue_t(int in = 0) : in_(in) {};
|
input_event_queue_t(int in = 0) : in_(in){};
|
||||||
|
|
||||||
/// Function used by input_readch to read bytes from stdin until enough bytes have been read to
|
/// Function used by input_readch to read bytes from stdin until enough bytes have been read to
|
||||||
/// convert them to a wchar_t. Conversion is done using mbrtowc. If a character has previously
|
/// convert them to a wchar_t. Conversion is done using mbrtowc. If a character has previously
|
||||||
|
|
|
@ -156,7 +156,7 @@ class maybe_t : private maybe_detail::conditionally_copyable_t<T> {
|
||||||
|
|
||||||
// Construct a value in-place.
|
// Construct a value in-place.
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
void emplace(Args &&... args) {
|
void emplace(Args &&...args) {
|
||||||
reset();
|
reset();
|
||||||
impl_.filled = true;
|
impl_.filled = true;
|
||||||
new (impl_.storage) T(std::forward<Args>(args)...);
|
new (impl_.storage) T(std::forward<Args>(args)...);
|
||||||
|
|
|
@ -208,7 +208,8 @@ enum class pipeline_position_t {
|
||||||
|
|
||||||
/// Error message on reaching maximum call stack depth.
|
/// Error message on reaching maximum call stack depth.
|
||||||
#define CALL_STACK_LIMIT_EXCEEDED_ERR_MSG \
|
#define CALL_STACK_LIMIT_EXCEEDED_ERR_MSG \
|
||||||
_(L"The function call stack limit has been exceeded. Do you have an accidental infinite loop?")
|
_(L"The function call stack limit has been exceeded. Do you have an accidental infinite " \
|
||||||
|
L"loop?")
|
||||||
|
|
||||||
/// Error message when encountering an illegal command name.
|
/// Error message when encountering an illegal command name.
|
||||||
#define ILLEGAL_CMD_ERR_MSG _(L"Illegal command name '%ls'")
|
#define ILLEGAL_CMD_ERR_MSG _(L"Illegal command name '%ls'")
|
||||||
|
|
|
@ -754,7 +754,8 @@ end_execution_reason_t parse_execution_context_t::handle_command_not_found(
|
||||||
|
|
||||||
// Redirect to stderr
|
// Redirect to stderr
|
||||||
auto io = io_chain_t{};
|
auto io = io_chain_t{};
|
||||||
io.append_from_specs({redirection_spec_t{STDOUT_FILENO, redirection_mode_t::fd, L"2"}}, L"");
|
io.append_from_specs({redirection_spec_t{STDOUT_FILENO, redirection_mode_t::fd, L"2"}},
|
||||||
|
L"");
|
||||||
|
|
||||||
if (function_exists(L"fish_command_not_found", *parser)) {
|
if (function_exists(L"fish_command_not_found", *parser)) {
|
||||||
buffer = L"fish_command_not_found";
|
buffer = L"fish_command_not_found";
|
||||||
|
|
|
@ -380,7 +380,8 @@ void safe_report_exec_error(int err, const char *actual_cmd, const char *const *
|
||||||
auto len = strlen(interpreter);
|
auto len = strlen(interpreter);
|
||||||
if (len && interpreter[len - 1] == '\r') {
|
if (len && interpreter[len - 1] == '\r') {
|
||||||
debug_safe(0,
|
debug_safe(0,
|
||||||
"The file uses windows line endings (\\r\\n). Run dos2unix or similar to fix it.");
|
"The file uses windows line endings (\\r\\n). Run dos2unix or "
|
||||||
|
"similar to fix it.");
|
||||||
} else {
|
} else {
|
||||||
debug_safe(0,
|
debug_safe(0,
|
||||||
"The file '%s' specified the interpreter '%s', which is not an "
|
"The file '%s' specified the interpreter '%s', which is not an "
|
||||||
|
|
|
@ -144,10 +144,10 @@ static operation_context_t get_bg_context(const std::shared_ptr<environment_t> &
|
||||||
return operation_context_t{nullptr, *env, std::move(cancel_checker)};
|
return operation_context_t{nullptr, *env, std::move(cancel_checker)};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We try to ensure that syntax highlighting completes appropriately before executing what the user typed.
|
/// We try to ensure that syntax highlighting completes appropriately before executing what the user
|
||||||
/// But we do not want it to block forever - e.g. it may hang on determining if an arbitrary argument
|
/// typed. But we do not want it to block forever - e.g. it may hang on determining if an arbitrary
|
||||||
/// is a path. This is how long we'll wait (in milliseconds) before giving up and performing a
|
/// argument is a path. This is how long we'll wait (in milliseconds) before giving up and
|
||||||
/// no-io syntax highlighting. See #7418, #5912.
|
/// performing a no-io syntax highlighting. See #7418, #5912.
|
||||||
static constexpr long kHighlightTimeoutForExecutionMs = 250;
|
static constexpr long kHighlightTimeoutForExecutionMs = 250;
|
||||||
|
|
||||||
/// Get the debouncer for autosuggestions and background highlighting.
|
/// Get the debouncer for autosuggestions and background highlighting.
|
||||||
|
@ -411,8 +411,7 @@ class reader_history_search_t {
|
||||||
// We can skip dedup in history_search_t because we do it ourselves in skips_.
|
// We can skip dedup in history_search_t because we do it ourselves in skips_.
|
||||||
search_ = history_search_t(
|
search_ = history_search_t(
|
||||||
*hist, text,
|
*hist, text,
|
||||||
by_prefix() ? history_search_type_t::prefix : history_search_type_t::contains,
|
by_prefix() ? history_search_type_t::prefix : history_search_type_t::contains, flags);
|
||||||
flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reset to inactive search.
|
/// Reset to inactive search.
|
||||||
|
@ -952,7 +951,7 @@ void reader_data_t::paint_layout(const wchar_t *reason) {
|
||||||
if (!conf.in_silent_mode && !data.history_search_text.empty()) {
|
if (!conf.in_silent_mode && !data.history_search_text.empty()) {
|
||||||
const wcstring &needle = data.history_search_text;
|
const wcstring &needle = data.history_search_text;
|
||||||
const wcstring &haystack = cmd_line->text();
|
const wcstring &haystack = cmd_line->text();
|
||||||
size_t match_pos = ifind(haystack,needle);
|
size_t match_pos = ifind(haystack, needle);
|
||||||
if (match_pos != wcstring::npos) {
|
if (match_pos != wcstring::npos) {
|
||||||
for (size_t i = 0; i < needle.size(); i++) {
|
for (size_t i = 0; i < needle.size(); i++) {
|
||||||
colors.at(match_pos + i).background = highlight_role_t::search_match;
|
colors.at(match_pos + i).background = highlight_role_t::search_match;
|
||||||
|
@ -2071,7 +2070,8 @@ static void acquire_tty_or_exit(pid_t shell_pgid) {
|
||||||
if (check_for_orphaned_process(loop_count, shell_pgid)) {
|
if (check_for_orphaned_process(loop_count, shell_pgid)) {
|
||||||
// We're orphaned, so we just die. Another sad statistic.
|
// We're orphaned, so we just die. Another sad statistic.
|
||||||
const wchar_t *fmt =
|
const wchar_t *fmt =
|
||||||
_(L"I appear to be an orphaned process, so I am quitting politely. My pid is %d.");
|
_(L"I appear to be an orphaned process, so I am quitting politely. My pid is "
|
||||||
|
L"%d.");
|
||||||
FLOGF(warning, fmt, static_cast<int>(getpid()));
|
FLOGF(warning, fmt, static_cast<int>(getpid()));
|
||||||
exit_without_destructors(1);
|
exit_without_destructors(1);
|
||||||
}
|
}
|
||||||
|
@ -2823,8 +2823,7 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
|
||||||
//
|
//
|
||||||
// Also paging is already cancelled above.
|
// Also paging is already cancelled above.
|
||||||
if (rls.complete_did_insert &&
|
if (rls.complete_did_insert &&
|
||||||
(rls.last_cmd == rl::complete
|
(rls.last_cmd == rl::complete || rls.last_cmd == rl::complete_and_search)) {
|
||||||
|| rls.last_cmd == rl::complete_and_search)) {
|
|
||||||
editable_line_t *el = active_edit_line();
|
editable_line_t *el = active_edit_line();
|
||||||
el->undo();
|
el->undo();
|
||||||
update_buff_pos(el);
|
update_buff_pos(el);
|
||||||
|
@ -3150,10 +3149,10 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
|
||||||
reader_history_search_t::mode_t mode =
|
reader_history_search_t::mode_t mode =
|
||||||
(c == rl::history_token_search_backward || c == rl::history_token_search_forward)
|
(c == rl::history_token_search_backward || c == rl::history_token_search_forward)
|
||||||
? reader_history_search_t::token
|
? reader_history_search_t::token
|
||||||
: (c == rl::history_prefix_search_backward ||
|
: (c == rl::history_prefix_search_backward ||
|
||||||
c == rl::history_prefix_search_forward)
|
c == rl::history_prefix_search_forward)
|
||||||
? reader_history_search_t::prefix
|
? reader_history_search_t::prefix
|
||||||
: reader_history_search_t::line;
|
: reader_history_search_t::line;
|
||||||
|
|
||||||
bool was_active_before = history_search.active();
|
bool was_active_before = history_search.active();
|
||||||
|
|
||||||
|
@ -3241,10 +3240,9 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
|
||||||
case rl::backward_kill_path_component:
|
case rl::backward_kill_path_component:
|
||||||
case rl::backward_kill_bigword: {
|
case rl::backward_kill_bigword: {
|
||||||
move_word_style_t style =
|
move_word_style_t style =
|
||||||
(c == rl::backward_kill_bigword
|
(c == rl::backward_kill_bigword ? move_word_style_whitespace
|
||||||
? move_word_style_whitespace
|
: c == rl::backward_kill_path_component ? move_word_style_path_components
|
||||||
: c == rl::backward_kill_path_component ? move_word_style_path_components
|
: move_word_style_punctuation);
|
||||||
: move_word_style_punctuation);
|
|
||||||
// Is this the same killring item as the last kill?
|
// Is this the same killring item as the last kill?
|
||||||
bool newv = (rls.last_cmd != rl::backward_kill_word &&
|
bool newv = (rls.last_cmd != rl::backward_kill_word &&
|
||||||
rls.last_cmd != rl::backward_kill_path_component &&
|
rls.last_cmd != rl::backward_kill_path_component &&
|
||||||
|
@ -3783,7 +3781,8 @@ maybe_t<wcstring> reader_data_t::readline(int nchars_or_0) {
|
||||||
|
|
||||||
// Redraw the command line. This is what ensures the autosuggestion is hidden, etc. after the
|
// Redraw the command line. This is what ensures the autosuggestion is hidden, etc. after the
|
||||||
// user presses enter.
|
// user presses enter.
|
||||||
if (this->is_repaint_needed() || conf.in != STDIN_FILENO) this->layout_and_repaint(L"prepare to execute");
|
if (this->is_repaint_needed() || conf.in != STDIN_FILENO)
|
||||||
|
this->layout_and_repaint(L"prepare to execute");
|
||||||
|
|
||||||
// Finish any outstanding syntax highlighting (but do not wait forever).
|
// Finish any outstanding syntax highlighting (but do not wait forever).
|
||||||
finish_highlighting_before_exec();
|
finish_highlighting_before_exec();
|
||||||
|
|
|
@ -430,7 +430,8 @@ wcstring normalize_path(const wcstring &path, bool allow_leading_double_slashes)
|
||||||
wcstring result = join_strings(new_comps, sep);
|
wcstring result = join_strings(new_comps, sep);
|
||||||
// Prepend one or two leading slashes.
|
// Prepend one or two leading slashes.
|
||||||
// Two slashes are preserved. Three+ slashes are collapsed to one. (!)
|
// Two slashes are preserved. Three+ slashes are collapsed to one. (!)
|
||||||
result.insert(0, allow_leading_double_slashes && leading_slashes > 2 ? 1 : leading_slashes, sep);
|
result.insert(0, allow_leading_double_slashes && leading_slashes > 2 ? 1 : leading_slashes,
|
||||||
|
sep);
|
||||||
// Ensure ./ normalizes to . and not empty.
|
// Ensure ./ normalizes to . and not empty.
|
||||||
if (result.empty()) result.push_back(L'.');
|
if (result.empty()) result.push_back(L'.');
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -309,5 +309,5 @@ expect_prompt("\nb c d")
|
||||||
# Check that ctrl-z can be bound
|
# Check that ctrl-z can be bound
|
||||||
sendline('bind \cz "echo bound ctrl-z"')
|
sendline('bind \cz "echo bound ctrl-z"')
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
send('\x1A')
|
send("\x1A")
|
||||||
expect_str("bound ctrl-z")
|
expect_str("bound ctrl-z")
|
||||||
|
|
|
@ -4,7 +4,13 @@ from pexpect_helper import SpawnedProc
|
||||||
import signal
|
import signal
|
||||||
|
|
||||||
sp = SpawnedProc()
|
sp = SpawnedProc()
|
||||||
send, sendline, sleep, expect_str, expect_prompt = sp.send, sp.sendline, sp.sleep, sp.expect_str, sp.expect_prompt
|
send, sendline, sleep, expect_str, expect_prompt = (
|
||||||
|
sp.send,
|
||||||
|
sp.sendline,
|
||||||
|
sp.sleep,
|
||||||
|
sp.expect_str,
|
||||||
|
sp.expect_prompt,
|
||||||
|
)
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
# Verify that cancel-commandline does what we expect - see #7384.
|
# Verify that cancel-commandline does what we expect - see #7384.
|
||||||
|
|
|
@ -50,9 +50,11 @@ expect_prompt()
|
||||||
# Verify that asking to exit a second time does so.
|
# Verify that asking to exit a second time does so.
|
||||||
send("exit\r")
|
send("exit\r")
|
||||||
|
|
||||||
for t in range(0,3):
|
for t in range(0, 3):
|
||||||
proc = subprocess.run(
|
proc = subprocess.run(
|
||||||
["pgrep", "-l", "-f", "sleep 11"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
["pgrep", "-l", "-f", "sleep 11"],
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
)
|
)
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
break
|
break
|
||||||
|
|
|
@ -18,11 +18,13 @@ expect_prompt()
|
||||||
sendline("test -t 0; echo $status")
|
sendline("test -t 0; echo $status")
|
||||||
expect_prompt("0")
|
expect_prompt("0")
|
||||||
|
|
||||||
sendline("""function t
|
sendline(
|
||||||
|
"""function t
|
||||||
test -t 0 && echo stdin
|
test -t 0 && echo stdin
|
||||||
test -t 1 && echo stdout
|
test -t 1 && echo stdout
|
||||||
test -t 2 && echo stderr
|
test -t 2 && echo stderr
|
||||||
end""")
|
end"""
|
||||||
|
)
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
sendline("t")
|
sendline("t")
|
||||||
|
|
|
@ -40,7 +40,7 @@ expect_re("Job.*Group.*(CPU)?.*State.*Command")
|
||||||
expect_re(".*running.*sleep 20 &")
|
expect_re(".*running.*sleep 20 &")
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
sendline("echo $my_pid")
|
sendline("echo $my_pid")
|
||||||
m = expect_re('\d+\r\n')
|
m = expect_re("\d+\r\n")
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
os.kill(int(m.group()), signal.SIGTERM)
|
os.kill(int(m.group()), signal.SIGTERM)
|
||||||
expect_re("[0-9]+:0:sleep 20 &:SIGTERM:Polite quit request", timeout=20)
|
expect_re("[0-9]+:0:sleep 20 &:SIGTERM:Polite quit request", timeout=20)
|
||||||
|
|
|
@ -7,7 +7,9 @@ sendline, expect_prompt, expect_str = sp.sendline, sp.expect_prompt, sp.expect_s
|
||||||
# Test fish_postexec and $status_generation for interactive shells.
|
# Test fish_postexec and $status_generation for interactive shells.
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
sendline("function test_fish_postexec --on-event fish_postexec; printf 'pipestatus:%s, generation:%d, command:%s\\n' (string join '|' $pipestatus) $status_generation $argv; end")
|
sendline(
|
||||||
|
"function test_fish_postexec --on-event fish_postexec; printf 'pipestatus:%s, generation:%d, command:%s\\n' (string join '|' $pipestatus) $status_generation $argv; end"
|
||||||
|
)
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
generation = 1
|
generation = 1
|
||||||
|
@ -38,7 +40,9 @@ expect_prompt()
|
||||||
|
|
||||||
# multiple backgrounded jobs
|
# multiple backgrounded jobs
|
||||||
sendline("sleep 1000 &; sleep 2000 &")
|
sendline("sleep 1000 &; sleep 2000 &")
|
||||||
expect_str("pipestatus:0|1, generation:%d, command:sleep 1000 &; sleep 2000 &" % generation)
|
expect_str(
|
||||||
|
"pipestatus:0|1, generation:%d, command:sleep 1000 &; sleep 2000 &" % generation
|
||||||
|
)
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
# valid variable assignment
|
# valid variable assignment
|
||||||
|
@ -48,18 +52,25 @@ expect_prompt()
|
||||||
|
|
||||||
# valid variable assignment with background job
|
# valid variable assignment with background job
|
||||||
sendline("set foo bar; sleep 1000 &")
|
sendline("set foo bar; sleep 1000 &")
|
||||||
expect_str("pipestatus:0|1, generation:%d, command:set foo bar; sleep 1000 &" % generation)
|
expect_str(
|
||||||
|
"pipestatus:0|1, generation:%d, command:set foo bar; sleep 1000 &" % generation
|
||||||
|
)
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
# Increments $status_generation if any job was foreground.
|
# Increments $status_generation if any job was foreground.
|
||||||
sendline("false|true; sleep 1000 &")
|
sendline("false|true; sleep 1000 &")
|
||||||
generation += 1
|
generation += 1
|
||||||
expect_str("pipestatus:1|0, generation:%d, command:false|true; sleep 1000 &" % generation)
|
expect_str(
|
||||||
|
"pipestatus:1|0, generation:%d, command:false|true; sleep 1000 &" % generation
|
||||||
|
)
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
sendline("sleep 1000 &; true|false|true")
|
sendline("sleep 1000 &; true|false|true")
|
||||||
generation += 1
|
generation += 1
|
||||||
expect_str("pipestatus:0|1|0, generation:%d, command:sleep 1000 &; true|false|true" % generation)
|
expect_str(
|
||||||
|
"pipestatus:0|1|0, generation:%d, command:sleep 1000 &; true|false|true"
|
||||||
|
% generation
|
||||||
|
)
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
# Increments $status_generation for empty if/while blocks.
|
# Increments $status_generation for empty if/while blocks.
|
||||||
|
@ -83,7 +94,9 @@ expect_prompt()
|
||||||
# This is an implementation detail, but the test case should prevent regressions.
|
# This is an implementation detail, but the test case should prevent regressions.
|
||||||
sendline("function fail; false; end")
|
sendline("function fail; false; end")
|
||||||
generation += 1
|
generation += 1
|
||||||
expect_str("pipestatus:0, generation:%d, command:function fail; false; end" % generation)
|
expect_str(
|
||||||
|
"pipestatus:0, generation:%d, command:function fail; false; end" % generation
|
||||||
|
)
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
# or an invalid variable assignment
|
# or an invalid variable assignment
|
||||||
|
@ -111,15 +124,24 @@ expect_prompt()
|
||||||
|
|
||||||
# Or begin/end block with only backgrounded jobs.
|
# Or begin/end block with only backgrounded jobs.
|
||||||
sendline("begin; sleep 200 &; sleep 400 &; end")
|
sendline("begin; sleep 200 &; sleep 400 &; end")
|
||||||
expect_str("pipestatus:0|1|0, generation:%d, command:begin; sleep 200 &; sleep 400 &; end" % generation)
|
expect_str(
|
||||||
|
"pipestatus:0|1|0, generation:%d, command:begin; sleep 200 &; sleep 400 &; end"
|
||||||
|
% generation
|
||||||
|
)
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
# Or a combination of begin/end block and backgrounded job.
|
# Or a combination of begin/end block and backgrounded job.
|
||||||
sendline("begin; sleep 200 &; end; sleep 400 &")
|
sendline("begin; sleep 200 &; end; sleep 400 &")
|
||||||
expect_str("pipestatus:0|1|0, generation:%d, command:begin; sleep 200 &; end; sleep 400 &" % generation)
|
expect_str(
|
||||||
|
"pipestatus:0|1|0, generation:%d, command:begin; sleep 200 &; end; sleep 400 &"
|
||||||
|
% generation
|
||||||
|
)
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
# Or a combination with variable assignments
|
# Or a combination with variable assignments
|
||||||
sendline("begin; set foo bar; sleep 1000 &; end; set bar baz; sleep 2000 &")
|
sendline("begin; set foo bar; sleep 1000 &; end; set bar baz; sleep 2000 &")
|
||||||
expect_str("pipestatus:0|1|0, generation:%d, command:begin; set foo bar; sleep 1000 &; end; set bar baz; sleep 2000 &" % generation)
|
expect_str(
|
||||||
|
"pipestatus:0|1|0, generation:%d, command:begin; set foo bar; sleep 1000 &; end; set bar baz; sleep 2000 &"
|
||||||
|
% generation
|
||||||
|
)
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
|
@ -41,7 +41,7 @@ expect_str("\x1b[33myellow")
|
||||||
expect_str("normal")
|
expect_str("normal")
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
sendline ("set_color --background blue --print-colors")
|
sendline("set_color --background blue --print-colors")
|
||||||
expect_str("black")
|
expect_str("black")
|
||||||
expect_str("blue")
|
expect_str("blue")
|
||||||
expect_str("brblack")
|
expect_str("brblack")
|
||||||
|
@ -60,4 +60,3 @@ expect_str("white")
|
||||||
expect_str("yellow")
|
expect_str("yellow")
|
||||||
expect_str("normal")
|
expect_str("normal")
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,9 @@ expect_prompt()
|
||||||
sendline("status job-control full")
|
sendline("status job-control full")
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
sendline("$fish -c 'status job-control full ; $fish_test_helper report_foreground' &; wait")
|
sendline(
|
||||||
|
"$fish -c 'status job-control full ; $fish_test_helper report_foreground' &; wait"
|
||||||
|
)
|
||||||
expect_prompt()
|
expect_prompt()
|
||||||
|
|
||||||
sendline("echo it worked")
|
sendline("echo it worked")
|
||||||
|
|
Loading…
Reference in a new issue