diff --git a/examples/dialogs/checkbox_dialog.py b/examples/dialogs/checkbox_dialog.py
index 90be2636ab..b267711896 100755
--- a/examples/dialogs/checkbox_dialog.py
+++ b/examples/dialogs/checkbox_dialog.py
@@ -2,11 +2,12 @@
"""
Example of a checkbox-list-based dialog.
"""
+
from prompt_toolkit.formatted_text import HTML
from prompt_toolkit.shortcuts import checkboxlist_dialog, message_dialog
from prompt_toolkit.styles import Style
-results = checkboxlist_dialog(
+if results := checkboxlist_dialog(
title="CheckboxList dialog",
text="What would you like in your breakfast ?",
values=[
@@ -26,8 +27,7 @@
"dialog.body label": "#fd8bb6",
}
),
-).run()
-if results:
+).run():
message_dialog(
title="Room service",
text="You selected: %s\nGreat choice sir !" % ",".join(results),
diff --git a/examples/full-screen/calculator.py b/examples/full-screen/calculator.py
index fda6567047..6bbc59e54c 100755
--- a/examples/full-screen/calculator.py
+++ b/examples/full-screen/calculator.py
@@ -50,9 +50,7 @@ def main():
def accept(buff):
# Evaluate "calculator" expression.
try:
- output = "\n\nIn: {}\nOut: {}".format(
- input_field.text, eval(input_field.text)
- ) # Don't do 'eval' in real code!
+ output = f"\n\nIn: {input_field.text}\nOut: {eval(input_field.text)}"
except BaseException as e:
output = f"\n\n{e}"
new_text = output_field.text + output
diff --git a/examples/full-screen/pager.py b/examples/full-screen/pager.py
index 799c834377..d6d925a7ad 100755
--- a/examples/full-screen/pager.py
+++ b/examples/full-screen/pager.py
@@ -25,13 +25,10 @@
def get_statusbar_text():
return [
- ("class:status", _pager_py_path + " - "),
+ ("class:status", f"{_pager_py_path} - "),
(
"class:status.position",
- "{}:{}".format(
- text_area.document.cursor_position_row + 1,
- text_area.document.cursor_position_col + 1,
- ),
+ f"{text_area.document.cursor_position_row + 1}:{text_area.document.cursor_position_col + 1}",
),
("class:status", " - Press "),
("class:status.key", "Ctrl-C"),
diff --git a/examples/full-screen/simple-demos/line-prefixes.py b/examples/full-screen/simple-demos/line-prefixes.py
index ab47ef6403..89bde1dd03 100755
--- a/examples/full-screen/simple-demos/line-prefixes.py
+++ b/examples/full-screen/simple-demos/line-prefixes.py
@@ -35,7 +35,7 @@ def get_line_prefix(lineno, wrap_count):
if wrap_count == 0:
return HTML('[%s] ') % lineno
- text = str(lineno) + "-" + "*" * (lineno // 2) + ": "
+ text = f"{str(lineno)}-" + "*" * (lineno // 2) + ": "
return HTML('[%s.%s] ') % (
lineno,
wrap_count,
diff --git a/examples/full-screen/text-editor.py b/examples/full-screen/text-editor.py
index 9c0a414201..624bc9357d 100755
--- a/examples/full-screen/text-editor.py
+++ b/examples/full-screen/text-editor.py
@@ -53,10 +53,7 @@ def get_statusbar_text():
def get_statusbar_right_text():
- return " {}:{} ".format(
- text_field.document.cursor_position_row + 1,
- text_field.document.cursor_position_col + 1,
- )
+ return f" {text_field.document.cursor_position_row + 1}:{text_field.document.cursor_position_col + 1} "
search_toolbar = SearchToolbar()
diff --git a/examples/print-text/named-colors.py b/examples/print-text/named-colors.py
index ea3f0ba0d6..177098d77f 100755
--- a/examples/print-text/named-colors.py
+++ b/examples/print-text/named-colors.py
@@ -11,7 +11,7 @@
def main():
- tokens = FormattedText([("fg:" + name, name + " ") for name in NAMED_COLORS])
+ tokens = FormattedText([(f"fg:{name}", f"{name} ") for name in NAMED_COLORS])
print(HTML("\nNamed colors, using 16 color output."))
print("(Note that it doesn't really make sense to use named colors ")
diff --git a/examples/print-text/true-color-demo.py b/examples/print-text/true-color-demo.py
index a241006065..000029d7c4 100755
--- a/examples/print-text/true-color-demo.py
+++ b/examples/print-text/true-color-demo.py
@@ -21,10 +21,7 @@ def main():
"bg:#00{0:02x}{0:02x}", # Cyan.
"bg:#{0:02x}{0:02x}{0:02x}", # Gray.
]:
- fragments = []
- for i in range(0, 256, 4):
- fragments.append((template.format(i), " "))
-
+ fragments = [(template.format(i), " ") for i in range(0, 256, 4)]
print(FormattedText(fragments), color_depth=ColorDepth.DEPTH_4_BIT)
print(FormattedText(fragments), color_depth=ColorDepth.DEPTH_8_BIT)
print(FormattedText(fragments), color_depth=ColorDepth.DEPTH_24_BIT)
diff --git a/examples/progress-bar/a-lot-of-parallel-tasks.py b/examples/progress-bar/a-lot-of-parallel-tasks.py
index 31110ac096..256b6f17e3 100755
--- a/examples/progress-bar/a-lot-of-parallel-tasks.py
+++ b/examples/progress-bar/a-lot-of-parallel-tasks.py
@@ -18,7 +18,7 @@ def main():
def run_task(label, total, sleep_time):
"""Complete a normal run."""
- for i in pb(range(total), label=label):
+ for _ in pb(range(total), label=label):
time.sleep(sleep_time)
def stop_task(label, total, sleep_time):
diff --git a/examples/progress-bar/colored-title-and-label.py b/examples/progress-bar/colored-title-and-label.py
index 0b5e73a225..248b6fcd82 100755
--- a/examples/progress-bar/colored-title-and-label.py
+++ b/examples/progress-bar/colored-title-and-label.py
@@ -14,7 +14,7 @@ def main():
label = HTML("some file: ")
with ProgressBar(title=title) as pb:
- for i in pb(range(800), label=label):
+ for _ in pb(range(800), label=label):
time.sleep(0.01)
diff --git a/examples/progress-bar/many-parallel-tasks.py b/examples/progress-bar/many-parallel-tasks.py
index dc34ef2eb2..b21c3188e1 100755
--- a/examples/progress-bar/many-parallel-tasks.py
+++ b/examples/progress-bar/many-parallel-tasks.py
@@ -16,7 +16,7 @@ def main():
) as pb:
def run_task(label, total, sleep_time):
- for i in pb(range(total), label=label):
+ for _ in pb(range(total), label=label):
time.sleep(sleep_time)
threads = [
diff --git a/examples/progress-bar/nested-progress-bars.py b/examples/progress-bar/nested-progress-bars.py
index a585ca1233..bb262f79e8 100755
--- a/examples/progress-bar/nested-progress-bars.py
+++ b/examples/progress-bar/nested-progress-bars.py
@@ -10,12 +10,12 @@
def main():
with ProgressBar(
- title=HTML('Nested progress bars'),
- bottom_toolbar=HTML(" [Control-L] clear [Control-C] abort"),
- ) as pb:
+ title=HTML('Nested progress bars'),
+ bottom_toolbar=HTML(" [Control-L] clear [Control-C] abort"),
+ ) as pb:
for i in pb(range(6), label="Main task"):
- for j in pb(range(200), label=f"Subtask <{i + 1}>", remove_when_done=True):
+ for _ in pb(range(200), label=f"Subtask <{i + 1}>", remove_when_done=True):
time.sleep(0.01)
diff --git a/examples/progress-bar/scrolling-task-name.py b/examples/progress-bar/scrolling-task-name.py
index bce155f0c5..83486ad683 100755
--- a/examples/progress-bar/scrolling-task-name.py
+++ b/examples/progress-bar/scrolling-task-name.py
@@ -10,9 +10,9 @@
def main():
with ProgressBar(
- title="Scrolling task name (make sure the window is not too big)."
- ) as pb:
- for i in pb(
+ title="Scrolling task name (make sure the window is not too big)."
+ ) as pb:
+ for _ in pb(
range(800),
label="This is a very very very long task that requires horizontal scrolling ...",
):
diff --git a/examples/progress-bar/simple-progress-bar.py b/examples/progress-bar/simple-progress-bar.py
index c8776e5036..a76aee6f25 100755
--- a/examples/progress-bar/simple-progress-bar.py
+++ b/examples/progress-bar/simple-progress-bar.py
@@ -10,7 +10,7 @@
def main():
with ProgressBar() as pb:
- for i in pb(range(800)):
+ for _ in pb(range(800)):
time.sleep(0.01)
diff --git a/examples/progress-bar/styled-1.py b/examples/progress-bar/styled-1.py
index d972e55e91..da58d9ae18 100755
--- a/examples/progress-bar/styled-1.py
+++ b/examples/progress-bar/styled-1.py
@@ -26,9 +26,9 @@
def main():
with ProgressBar(
- style=style, title="Progress bar example with custom styling."
- ) as pb:
- for i in pb(range(1600), label="Downloading..."):
+ style=style, title="Progress bar example with custom styling."
+ ) as pb:
+ for _ in pb(range(1600), label="Downloading..."):
time.sleep(0.01)
diff --git a/examples/progress-bar/styled-2.py b/examples/progress-bar/styled-2.py
index eb2c479c27..cac0eb4d35 100755
--- a/examples/progress-bar/styled-2.py
+++ b/examples/progress-bar/styled-2.py
@@ -37,12 +37,12 @@ def main():
formatters.TimeLeft(),
]
with ProgressBar(
- title="Progress bar example with custom formatter.",
- formatters=custom_formatters,
- style=style,
- ) as pb:
+ title="Progress bar example with custom formatter.",
+ formatters=custom_formatters,
+ style=style,
+ ) as pb:
- for i in pb(range(20), label="Downloading..."):
+ for _ in pb(range(20), label="Downloading..."):
time.sleep(1)
diff --git a/examples/progress-bar/styled-apt-get-install.py b/examples/progress-bar/styled-apt-get-install.py
index bafe70ba43..4105e20f8a 100755
--- a/examples/progress-bar/styled-apt-get-install.py
+++ b/examples/progress-bar/styled-apt-get-install.py
@@ -30,7 +30,7 @@ def main():
]
with ProgressBar(style=style, formatters=custom_formatters) as pb:
- for i in pb(range(1600), label="Installing"):
+ for _ in pb(range(1600), label="Installing"):
time.sleep(0.01)
diff --git a/examples/progress-bar/styled-rainbow.py b/examples/progress-bar/styled-rainbow.py
index e45a91632b..2f0dbbc70d 100755
--- a/examples/progress-bar/styled-rainbow.py
+++ b/examples/progress-bar/styled-rainbow.py
@@ -21,13 +21,9 @@ def main():
formatters.Rainbow(formatters.TimeLeft()),
]
- if true_color:
- color_depth = ColorDepth.DEPTH_24_BIT
- else:
- color_depth = ColorDepth.DEPTH_8_BIT
-
+ color_depth = ColorDepth.DEPTH_24_BIT if true_color else ColorDepth.DEPTH_8_BIT
with ProgressBar(formatters=custom_formatters, color_depth=color_depth) as pb:
- for i in pb(range(20), label="Downloading..."):
+ for _ in pb(range(20), label="Downloading..."):
time.sleep(1)
diff --git a/examples/progress-bar/styled-tqdm-1.py b/examples/progress-bar/styled-tqdm-1.py
index 9484ac051b..f9b6e020e8 100755
--- a/examples/progress-bar/styled-tqdm-1.py
+++ b/examples/progress-bar/styled-tqdm-1.py
@@ -32,7 +32,7 @@ def main():
]
with ProgressBar(style=style, formatters=custom_formatters) as pb:
- for i in pb(range(1600), label="Installing"):
+ for _ in pb(range(1600), label="Installing"):
time.sleep(0.01)
diff --git a/examples/progress-bar/styled-tqdm-2.py b/examples/progress-bar/styled-tqdm-2.py
index 0e66e90073..720179b39d 100755
--- a/examples/progress-bar/styled-tqdm-2.py
+++ b/examples/progress-bar/styled-tqdm-2.py
@@ -30,7 +30,7 @@ def main():
]
with ProgressBar(style=style, formatters=custom_formatters) as pb:
- for i in pb(range(1600), label="Installing"):
+ for _ in pb(range(1600), label="Installing"):
time.sleep(0.01)
diff --git a/examples/progress-bar/two-tasks.py b/examples/progress-bar/two-tasks.py
index c78604ef4d..33c0271ecf 100755
--- a/examples/progress-bar/two-tasks.py
+++ b/examples/progress-bar/two-tasks.py
@@ -12,11 +12,11 @@ def main():
with ProgressBar() as pb:
# Two parallal tasks.
def task_1():
- for i in pb(range(100)):
+ for _ in pb(range(100)):
time.sleep(0.05)
def task_2():
- for i in pb(range(150)):
+ for _ in pb(range(150)):
time.sleep(0.08)
# Start threads.
diff --git a/examples/progress-bar/unknown-length.py b/examples/progress-bar/unknown-length.py
index e39ac399dc..d6d8c5325f 100755
--- a/examples/progress-bar/unknown-length.py
+++ b/examples/progress-bar/unknown-length.py
@@ -18,7 +18,7 @@ def data():
def main():
with ProgressBar() as pb:
- for i in pb(data()):
+ for _ in pb(data()):
time.sleep(0.1)
diff --git a/examples/prompts/accept-default.py b/examples/prompts/accept-default.py
index 311ef46c96..0ef45d986d 100644
--- a/examples/prompts/accept-default.py
+++ b/examples/prompts/accept-default.py
@@ -6,6 +6,7 @@
This should display the prompt with all the formatting like usual, but not
allow any editing.
"""
+
from prompt_toolkit import HTML, prompt
if __name__ == "__main__":
@@ -13,4 +14,4 @@
HTML("Type some input: "), accept_default=True, default="test"
)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
diff --git a/examples/prompts/auto-completion/autocomplete-with-control-space.py b/examples/prompts/auto-completion/autocomplete-with-control-space.py
index 61160a3626..dad7b2475b 100755
--- a/examples/prompts/auto-completion/autocomplete-with-control-space.py
+++ b/examples/prompts/auto-completion/autocomplete-with-control-space.py
@@ -68,7 +68,7 @@ def main():
complete_while_typing=False,
key_bindings=kb,
)
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/prompts/auto-completion/autocompletion-like-readline.py b/examples/prompts/auto-completion/autocompletion-like-readline.py
index 613d3e7408..31835b3279 100755
--- a/examples/prompts/auto-completion/autocompletion-like-readline.py
+++ b/examples/prompts/auto-completion/autocompletion-like-readline.py
@@ -51,7 +51,7 @@ def main():
completer=animal_completer,
complete_style=CompleteStyle.READLINE_LIKE,
)
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/prompts/auto-completion/autocompletion.py b/examples/prompts/auto-completion/autocompletion.py
index fc9dda0589..34b4d926b4 100755
--- a/examples/prompts/auto-completion/autocompletion.py
+++ b/examples/prompts/auto-completion/autocompletion.py
@@ -53,7 +53,7 @@ def main():
text = prompt(
"Give some animals: ", completer=animal_completer, complete_while_typing=False
)
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/prompts/auto-completion/colored-completions.py b/examples/prompts/auto-completion/colored-completions.py
index 9c5cba365b..ed10075374 100755
--- a/examples/prompts/auto-completion/colored-completions.py
+++ b/examples/prompts/auto-completion/colored-completions.py
@@ -28,8 +28,8 @@ def get_completions(self, document, complete_event):
yield Completion(
color,
start_position=-len(word),
- style="fg:" + color,
- selected_style="fg:white bg:" + color,
+ style=f"fg:{color}",
+ selected_style=f"fg:white bg:{color}",
)
diff --git a/examples/prompts/auto-completion/combine-multiple-completers.py b/examples/prompts/auto-completion/combine-multiple-completers.py
index 273ebe561d..67237b1c6a 100755
--- a/examples/prompts/auto-completion/combine-multiple-completers.py
+++ b/examples/prompts/auto-completion/combine-multiple-completers.py
@@ -69,7 +69,7 @@ def main():
text = prompt(
"Give some animals: ", completer=completer, complete_while_typing=False
)
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/prompts/auto-completion/fuzzy-custom-completer.py b/examples/prompts/auto-completion/fuzzy-custom-completer.py
index 405292946b..3896929393 100755
--- a/examples/prompts/auto-completion/fuzzy-custom-completer.py
+++ b/examples/prompts/auto-completion/fuzzy-custom-completer.py
@@ -28,8 +28,8 @@ def get_completions(self, document, complete_event):
yield Completion(
color,
start_position=-len(word),
- style="fg:" + color,
- selected_style="fg:white bg:" + color,
+ style=f"fg:{color}",
+ selected_style=f"fg:white bg:{color}",
)
diff --git a/examples/prompts/auto-completion/fuzzy-word-completer.py b/examples/prompts/auto-completion/fuzzy-word-completer.py
index 329c0c1e36..616d7db82c 100755
--- a/examples/prompts/auto-completion/fuzzy-word-completer.py
+++ b/examples/prompts/auto-completion/fuzzy-word-completer.py
@@ -52,7 +52,7 @@ def main():
text = prompt(
"Give some animals: ", completer=animal_completer, complete_while_typing=True
)
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/prompts/auto-completion/multi-column-autocompletion-with-meta.py b/examples/prompts/auto-completion/multi-column-autocompletion-with-meta.py
index 5ba3ab5088..a9f9bd5184 100755
--- a/examples/prompts/auto-completion/multi-column-autocompletion-with-meta.py
+++ b/examples/prompts/auto-completion/multi-column-autocompletion-with-meta.py
@@ -43,7 +43,7 @@ def main():
completer=animal_completer,
complete_style=CompleteStyle.MULTI_COLUMN,
)
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/prompts/auto-completion/multi-column-autocompletion.py b/examples/prompts/auto-completion/multi-column-autocompletion.py
index 7fcfc52cbc..cdc745d972 100755
--- a/examples/prompts/auto-completion/multi-column-autocompletion.py
+++ b/examples/prompts/auto-completion/multi-column-autocompletion.py
@@ -50,7 +50,7 @@ def main():
completer=animal_completer,
complete_style=CompleteStyle.MULTI_COLUMN,
)
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/prompts/auto-completion/nested-autocompletion.py b/examples/prompts/auto-completion/nested-autocompletion.py
index cd85b8cb49..ea45f595ed 100755
--- a/examples/prompts/auto-completion/nested-autocompletion.py
+++ b/examples/prompts/auto-completion/nested-autocompletion.py
@@ -15,7 +15,7 @@
def main():
text = prompt("Type a command: ", completer=completer)
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/prompts/auto-suggestion.py b/examples/prompts/auto-suggestion.py
index 6660777804..97438ee930 100755
--- a/examples/prompts/auto-suggestion.py
+++ b/examples/prompts/auto-suggestion.py
@@ -41,7 +41,7 @@ def main():
else:
break
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/prompts/autocorrection.py b/examples/prompts/autocorrection.py
index 63781326af..53bf2a369e 100755
--- a/examples/prompts/autocorrection.py
+++ b/examples/prompts/autocorrection.py
@@ -28,10 +28,9 @@ def _(event):
b = event.app.current_buffer
w = b.document.get_word_before_cursor()
- if w is not None:
- if w in corrections:
- b.delete_before_cursor(count=len(w))
- b.insert_text(corrections[w])
+ if w is not None and w in corrections:
+ b.delete_before_cursor(count=len(w))
+ b.insert_text(corrections[w])
b.insert_text(" ")
diff --git a/examples/prompts/clock-input.py b/examples/prompts/clock-input.py
index e43abd8915..e1b8b5de1f 100755
--- a/examples/prompts/clock-input.py
+++ b/examples/prompts/clock-input.py
@@ -18,7 +18,7 @@ def get_prompt():
def main():
result = prompt(get_prompt, refresh_interval=0.5)
- print("You said: %s" % result)
+ print(f"You said: {result}")
if __name__ == "__main__":
diff --git a/examples/prompts/colored-prompt.py b/examples/prompts/colored-prompt.py
index 1e63e296b1..f3f7f3e92b 100755
--- a/examples/prompts/colored-prompt.py
+++ b/examples/prompts/colored-prompt.py
@@ -40,7 +40,7 @@ def example_1():
]
answer = prompt(prompt_fragments, style=style)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
def example_2():
@@ -57,7 +57,7 @@ def example_2():
),
style=style,
)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
def example_3():
@@ -72,7 +72,7 @@ def example_3():
"# "
)
)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
if __name__ == "__main__":
diff --git a/examples/prompts/confirmation-prompt.py b/examples/prompts/confirmation-prompt.py
index bd52b9e96a..18687fe6c4 100755
--- a/examples/prompts/confirmation-prompt.py
+++ b/examples/prompts/confirmation-prompt.py
@@ -2,8 +2,9 @@
"""
Example of a confirmation prompt.
"""
+
from prompt_toolkit.shortcuts import confirm
if __name__ == "__main__":
answer = confirm("Should we do that?")
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
diff --git a/examples/prompts/custom-key-binding.py b/examples/prompts/custom-key-binding.py
index 32d889ede0..1f1615ebf4 100755
--- a/examples/prompts/custom-key-binding.py
+++ b/examples/prompts/custom-key-binding.py
@@ -60,7 +60,7 @@ async def _(event):
Example of asyncio coroutine as a key binding.
"""
try:
- for i in range(5):
+ for _ in range(5):
async with in_terminal():
print("hello")
await asyncio.sleep(1)
diff --git a/examples/prompts/custom-lexer.py b/examples/prompts/custom-lexer.py
index 1255d9f3f9..5c53f6a1ce 100755
--- a/examples/prompts/custom-lexer.py
+++ b/examples/prompts/custom-lexer.py
@@ -22,7 +22,7 @@ def get_line(lineno):
def main():
answer = prompt("Give me some input: ", lexer=RainbowLexer())
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
if __name__ == "__main__":
diff --git a/examples/prompts/fancy-zsh-prompt.py b/examples/prompts/fancy-zsh-prompt.py
index 4761c08ad0..a8fc846f53 100755
--- a/examples/prompts/fancy-zsh-prompt.py
+++ b/examples/prompts/fancy-zsh-prompt.py
@@ -72,7 +72,7 @@ def get_prompt() -> HTML:
def main() -> None:
while True:
answer = prompt(get_prompt, style=style, refresh_interval=1)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
if __name__ == "__main__":
diff --git a/examples/prompts/finalterm-shell-integration.py b/examples/prompts/finalterm-shell-integration.py
index 30c7a7fb33..379b5a433f 100755
--- a/examples/prompts/finalterm-shell-integration.py
+++ b/examples/prompts/finalterm-shell-integration.py
@@ -39,5 +39,5 @@ def get_prompt_text():
# Output.
sys.stdout.write(BEFORE_OUTPUT)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
sys.stdout.write(AFTER_OUTPUT.format(command_status=0))
diff --git a/examples/prompts/get-input-vi-mode.py b/examples/prompts/get-input-vi-mode.py
index 566ffd5ed5..4073bcdd2b 100755
--- a/examples/prompts/get-input-vi-mode.py
+++ b/examples/prompts/get-input-vi-mode.py
@@ -4,4 +4,4 @@
if __name__ == "__main__":
print("You have Vi keybindings here. Press [Esc] to go to navigation mode.")
answer = prompt("Give me some input: ", multiline=False, vi_mode=True)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
diff --git a/examples/prompts/get-input-with-default.py b/examples/prompts/get-input-with-default.py
index 67446d57f9..974888f951 100755
--- a/examples/prompts/get-input-with-default.py
+++ b/examples/prompts/get-input-with-default.py
@@ -3,10 +3,11 @@
Example of a call to `prompt` with a default value.
The input is pre-filled, but the user can still edit the default.
"""
+
import getpass
from prompt_toolkit import prompt
if __name__ == "__main__":
- answer = prompt("What is your name: ", default="%s" % getpass.getuser())
- print("You said: %s" % answer)
+ answer = prompt("What is your name: ", default=f"{getpass.getuser()}")
+ print(f"You said: {answer}")
diff --git a/examples/prompts/get-input.py b/examples/prompts/get-input.py
index 5529bbbb5b..6db7e2c49e 100755
--- a/examples/prompts/get-input.py
+++ b/examples/prompts/get-input.py
@@ -2,8 +2,9 @@
"""
The most simple prompt example.
"""
+
from prompt_toolkit import prompt
if __name__ == "__main__":
answer = prompt("Give me some input: ")
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
diff --git a/examples/prompts/get-multiline-input.py b/examples/prompts/get-multiline-input.py
index eda35bee42..48bcb1903a 100755
--- a/examples/prompts/get-multiline-input.py
+++ b/examples/prompts/get-multiline-input.py
@@ -16,9 +16,8 @@ def prompt_continuation(width, line_number, wrap_count):
"""
if wrap_count > 0:
return " " * (width - 3) + "-> "
- else:
- text = ("- %i - " % (line_number + 1)).rjust(width)
- return HTML("%s") % text
+ text = ("- %i - " % (line_number + 1)).rjust(width)
+ return HTML("%s") % text
if __name__ == "__main__":
@@ -26,4 +25,4 @@ def prompt_continuation(width, line_number, wrap_count):
answer = prompt(
"Multiline input: ", multiline=True, prompt_continuation=prompt_continuation
)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
diff --git a/examples/prompts/get-password.py b/examples/prompts/get-password.py
index 1c9517c60f..a9c0c27f78 100755
--- a/examples/prompts/get-password.py
+++ b/examples/prompts/get-password.py
@@ -3,4 +3,4 @@
if __name__ == "__main__":
password = prompt("Password: ", is_password=True)
- print("You said: %s" % password)
+ print(f"You said: {password}")
diff --git a/examples/prompts/history/persistent-history.py b/examples/prompts/history/persistent-history.py
index 2bdb7587f4..395bfdfd97 100755
--- a/examples/prompts/history/persistent-history.py
+++ b/examples/prompts/history/persistent-history.py
@@ -18,7 +18,7 @@ def main():
while True:
text = session.prompt("Say something: ")
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/prompts/history/slow-history.py b/examples/prompts/history/slow-history.py
index 5b6a7a2f54..ccc0270775 100755
--- a/examples/prompts/history/slow-history.py
+++ b/examples/prompts/history/slow-history.py
@@ -41,7 +41,7 @@ def main():
while True:
text = session.prompt("Say something: ")
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/prompts/html-input.py b/examples/prompts/html-input.py
index 4c51737773..ce3575130b 100755
--- a/examples/prompts/html-input.py
+++ b/examples/prompts/html-input.py
@@ -11,7 +11,7 @@
def main():
text = prompt("Enter HTML: ", lexer=PygmentsLexer(HtmlLexer))
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/prompts/input-validation.py b/examples/prompts/input-validation.py
index d8bd3eef94..18e0b117f8 100755
--- a/examples/prompts/input-validation.py
+++ b/examples/prompts/input-validation.py
@@ -22,13 +22,13 @@ def main():
text = prompt(
"Enter e-mail address: ", validator=validator, validate_while_typing=False
)
- print("You said: %s" % text)
+ print(f"You said: {text}")
# While typing
text = prompt(
"Enter e-mail address: ", validator=validator, validate_while_typing=True
)
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/prompts/inputhook.py b/examples/prompts/inputhook.py
index 852079042f..d75f53f29d 100755
--- a/examples/prompts/inputhook.py
+++ b/examples/prompts/inputhook.py
@@ -77,7 +77,7 @@ def main():
"Python >>> ", inputhook=inputhook, lexer=PygmentsLexer(PythonLexer)
)
result = session.prompt()
- print("You said: %s" % result)
+ print(f"You said: {result}")
if __name__ == "__main__":
diff --git a/examples/prompts/mouse-support.py b/examples/prompts/mouse-support.py
index 1e4ee76005..b1b4bb70ed 100755
--- a/examples/prompts/mouse-support.py
+++ b/examples/prompts/mouse-support.py
@@ -7,4 +7,4 @@
)
print("You can click with the mouse in order to select text.")
answer = prompt("Multiline input: ", multiline=True, mouse_support=True)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
diff --git a/examples/prompts/multiline-prompt.py b/examples/prompts/multiline-prompt.py
index d6a7698cbc..f2e70ef30e 100755
--- a/examples/prompts/multiline-prompt.py
+++ b/examples/prompts/multiline-prompt.py
@@ -2,10 +2,11 @@
"""
Demonstration of how the input can be indented.
"""
+
from prompt_toolkit import prompt
if __name__ == "__main__":
answer = prompt(
"Give me some input: (ESCAPE followed by ENTER to accept)\n > ", multiline=True
)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
diff --git a/examples/prompts/no-wrapping.py b/examples/prompts/no-wrapping.py
index 371486ea66..170e7d53c8 100755
--- a/examples/prompts/no-wrapping.py
+++ b/examples/prompts/no-wrapping.py
@@ -3,4 +3,4 @@
if __name__ == "__main__":
answer = prompt("Give me some input: ", wrap_lines=False, multiline=True)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
diff --git a/examples/prompts/placeholder-text.py b/examples/prompts/placeholder-text.py
index e113330280..46d1ce5086 100755
--- a/examples/prompts/placeholder-text.py
+++ b/examples/prompts/placeholder-text.py
@@ -2,6 +2,7 @@
"""
Example of a placeholer that's displayed as long as no input is given.
"""
+
from prompt_toolkit import prompt
from prompt_toolkit.formatted_text import HTML
@@ -10,4 +11,4 @@
"Give me some input: ",
placeholder=HTML(''),
)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
diff --git a/examples/prompts/regular-language.py b/examples/prompts/regular-language.py
index cbe7256da8..59a39152e4 100755
--- a/examples/prompts/regular-language.py
+++ b/examples/prompts/regular-language.py
@@ -72,8 +72,7 @@ def create_grammar():
text = prompt(
"Calculate: ", lexer=lexer, completer=completer, style=example_style
)
- m = g.match(text)
- if m:
+ if m := g.match(text):
vars = m.variables()
else:
print("Invalid command\n")
diff --git a/examples/prompts/rprompt.py b/examples/prompts/rprompt.py
index f7656b7af6..b78653e48b 100755
--- a/examples/prompts/rprompt.py
+++ b/examples/prompts/rprompt.py
@@ -30,23 +30,23 @@ def get_rprompt_text():
def main():
# Option 1: pass a string to 'rprompt':
answer = prompt("> ", rprompt=" ", style=example_style)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
# Option 2: pass HTML:
answer = prompt("> ", rprompt=HTML(" <rprompt> "), style=example_style)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
# Option 3: pass ANSI:
answer = prompt(
"> ", rprompt=ANSI(" \x1b[4m\x1b[0m "), style=example_style
)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
# Option 4: Pass a callable. (This callable can either return plain text,
# an HTML object, an ANSI object or a list of (style, text)
# tuples.
answer = prompt("> ", rprompt=get_rprompt_text, style=example_style)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
if __name__ == "__main__":
diff --git a/examples/prompts/swap-light-and-dark-colors.py b/examples/prompts/swap-light-and-dark-colors.py
index e602449d45..8f5e9d8762 100755
--- a/examples/prompts/swap-light-and-dark-colors.py
+++ b/examples/prompts/swap-light-and-dark-colors.py
@@ -48,11 +48,7 @@ def _(event):
swapped[0] = not swapped[0]
def bottom_toolbar():
- if swapped[0]:
- on = "on=true"
- else:
- on = "on=false"
-
+ on = "on=true" if swapped[0] else "on=false"
return (
HTML(
'Press '
diff --git a/examples/prompts/system-clipboard-integration.py b/examples/prompts/system-clipboard-integration.py
index f6059217fb..0b9136b9bd 100755
--- a/examples/prompts/system-clipboard-integration.py
+++ b/examples/prompts/system-clipboard-integration.py
@@ -3,6 +3,7 @@
Demonstration of a custom clipboard class.
This requires the 'pyperclip' library to be installed.
"""
+
from prompt_toolkit import prompt
from prompt_toolkit.clipboard.pyperclip import PyperclipClipboard
@@ -14,4 +15,4 @@
print("")
answer = prompt("Give me some input: ", clipboard=PyperclipClipboard())
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
diff --git a/examples/prompts/system-prompt.py b/examples/prompts/system-prompt.py
index 47aa2a5620..e9ff46095b 100755
--- a/examples/prompts/system-prompt.py
+++ b/examples/prompts/system-prompt.py
@@ -7,14 +7,14 @@
"(1/3) If you press meta-! or esc-! at the following prompt, you can enter system commands."
)
answer = prompt("Give me some input: ", enable_system_prompt=True)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
# Enable suspend.
print("(2/3) If you press Control-Z, the application will suspend.")
answer = prompt("Give me some input: ", enable_suspend=True)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
# Enable open_in_editor
print("(3/3) If you press Control-X Control-E, the prompt will open in $EDITOR.")
answer = prompt("Give me some input: ", enable_open_in_editor=True)
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
diff --git a/examples/prompts/terminal-title.py b/examples/prompts/terminal-title.py
index 14f945999c..dc49c2671a 100755
--- a/examples/prompts/terminal-title.py
+++ b/examples/prompts/terminal-title.py
@@ -7,4 +7,4 @@
answer = prompt("Give me some input: ")
set_title("")
- print("You said: %s" % answer)
+ print(f"You said: {answer}")
diff --git a/examples/prompts/up-arrow-partial-string-matching.py b/examples/prompts/up-arrow-partial-string-matching.py
index 742a12eda2..8ff704559d 100755
--- a/examples/prompts/up-arrow-partial-string-matching.py
+++ b/examples/prompts/up-arrow-partial-string-matching.py
@@ -34,7 +34,7 @@ def main():
else:
break
- print("You said: %s" % text)
+ print(f"You said: {text}")
if __name__ == "__main__":
diff --git a/examples/ssh/asyncssh-server.py b/examples/ssh/asyncssh-server.py
index 1fa1800a46..2192610897 100755
--- a/examples/ssh/asyncssh-server.py
+++ b/examples/ssh/asyncssh-server.py
@@ -73,7 +73,7 @@ async def interact(ssh_session: PromptToolkitSSHSession) -> None:
# Simple progress bar.
with ProgressBar() as pb:
- for i in pb(range(50)):
+ for _ in pb(range(50)):
await asyncio.sleep(0.1)
# Normal prompt.
diff --git a/examples/telnet/chat-app.py b/examples/telnet/chat-app.py
index 1880a362b9..5b0bc72f52 100755
--- a/examples/telnet/chat-app.py
+++ b/examples/telnet/chat-app.py
@@ -84,9 +84,9 @@ def _send_to_everyone(sender_connection, name, message, color):
if c != sender_connection:
c.send_above_prompt(
[
- ("fg:" + color, "[%s]" % name),
+ (f"fg:{color}", f"[{name}]"),
("", " "),
- ("fg:" + color, "%s\n" % message),
+ (f"fg:{color}", "%s\n" % message),
]
)
diff --git a/examples/tutorial/sqlite-cli.py b/examples/tutorial/sqlite-cli.py
index ea3e2c81c4..11c6f32f97 100755
--- a/examples/tutorial/sqlite-cli.py
+++ b/examples/tutorial/sqlite-cli.py
@@ -176,9 +176,5 @@ def main(database):
if __name__ == "__main__":
- if len(sys.argv) < 2:
- db = ":memory:"
- else:
- db = sys.argv[1]
-
+ db = ":memory:" if len(sys.argv) < 2 else sys.argv[1]
main(db)
diff --git a/setup.py b/setup.py
index 567e58e47d..555176784a 100755
--- a/setup.py
+++ b/setup.py
@@ -15,7 +15,7 @@ def get_version(package):
path = os.path.join(os.path.dirname(__file__), "src", package, "__init__.py")
with open(path, "rb") as f:
init_py = f.read().decode("utf-8")
- return re.search("__version__ = ['\"]([^'\"]+)['\"]", init_py).group(1)
+ return re.search("__version__ = ['\"]([^'\"]+)['\"]", init_py)[1]
setup(
diff --git a/src/prompt_toolkit/application/application.py b/src/prompt_toolkit/application/application.py
index 5a09918da5..d99a322036 100644
--- a/src/prompt_toolkit/application/application.py
+++ b/src/prompt_toolkit/application/application.py
@@ -359,10 +359,7 @@ def _create_merged_style(self, include_default_pygments_style: Filter) -> BaseSt
@DynamicStyle
def conditional_pygments_style() -> BaseStyle:
- if include_default_pygments_style():
- return pygments_style
- else:
- return dummy_style
+ return pygments_style if include_default_pygments_style() else dummy_style
return merge_styles(
[
@@ -521,29 +518,30 @@ def _redraw(self, render_as_done: bool = False) -> None:
def run_in_context() -> None:
# Only draw when no sub application was started.
- if self._is_running and not self._running_in_terminal:
- if self.min_redraw_interval:
- self._last_redraw_time = time.time()
-
- # Render
- self.render_counter += 1
- self.before_render.fire()
-
- if render_as_done:
- if self.erase_when_done:
- self.renderer.erase()
- else:
- # Draw in 'done' state and reset renderer.
- self.renderer.render(self, self.layout, is_done=render_as_done)
+ if not self._is_running or self._running_in_terminal:
+ return
+ if self.min_redraw_interval:
+ self._last_redraw_time = time.time()
+
+ # Render
+ self.render_counter += 1
+ self.before_render.fire()
+
+ if render_as_done:
+ if self.erase_when_done:
+ self.renderer.erase()
else:
- self.renderer.render(self, self.layout)
+ # Draw in 'done' state and reset renderer.
+ self.renderer.render(self, self.layout, is_done=render_as_done)
+ else:
+ self.renderer.render(self, self.layout)
- self.layout.update_parents_relations()
+ self.layout.update_parents_relations()
- # Fire render event.
- self.after_render.fire()
+ # Fire render event.
+ self.after_render.fire()
- self._update_invalidate_events()
+ self._update_invalidate_events()
# NOTE: We want to make sure this Application is the active one. The
# invalidate function is often called from a context where this
@@ -962,7 +960,7 @@ async def in_term() -> None:
# but don't use logger. (This works better on Python 2.)
print("\nUnhandled exception in event loop:")
print(formatted_tb)
- print("Exception {}".format(context.get("exception")))
+ print(f'Exception {context.get("exception")}')
await _do_wait_for_enter("Press ENTER to continue...")
@@ -1246,18 +1244,14 @@ def is_running(self) -> bool:
@property
def is_done(self) -> bool:
- if self.future:
- return self.future.done()
- return False
+ return self.future.done() if self.future else False
def get_used_style_strings(self) -> List[str]:
"""
Return a list of used style strings. This is helpful for debugging, and
for writing a new `Style`.
"""
- attrs_for_style = self.renderer._attrs_for_style
-
- if attrs_for_style:
+ if attrs_for_style := self.renderer._attrs_for_style:
return sorted(
re.sub(r"\s+", " ", style_str).strip()
for style_str in attrs_for_style.keys()
@@ -1329,14 +1323,15 @@ def _create_key_bindings(
if self.app.key_bindings:
key_bindings.append(self.app.key_bindings)
- # Add mouse bindings.
- key_bindings.append(
- ConditionalKeyBindings(
- self.app._page_navigation_bindings,
- self.app.enable_page_navigation_bindings,
+ key_bindings.extend(
+ (
+ ConditionalKeyBindings(
+ self.app._page_navigation_bindings,
+ self.app.enable_page_navigation_bindings,
+ ),
+ self.app._default_bindings,
)
)
- key_bindings.append(self.app._default_bindings)
# Reverse this list. The current control's key bindings should come
# last. They need priority.
diff --git a/src/prompt_toolkit/application/run_in_terminal.py b/src/prompt_toolkit/application/run_in_terminal.py
index d5ef8aafa3..a66e5dc794 100644
--- a/src/prompt_toolkit/application/run_in_terminal.py
+++ b/src/prompt_toolkit/application/run_in_terminal.py
@@ -50,10 +50,7 @@ def run_in_terminal(
async def run() -> _T:
async with in_terminal(render_cli_done=render_cli_done):
- if in_executor:
- return await run_in_executor_with_context(func)
- else:
- return func()
+ return await run_in_executor_with_context(func) if in_executor else func()
return ensure_future(run())
diff --git a/src/prompt_toolkit/auto_suggest.py b/src/prompt_toolkit/auto_suggest.py
index 7099b8e974..7a8d1b63ac 100644
--- a/src/prompt_toolkit/auto_suggest.py
+++ b/src/prompt_toolkit/auto_suggest.py
@@ -44,7 +44,7 @@ def __init__(self, text: str) -> None:
self.text = text
def __repr__(self) -> str:
- return "Suggestion(%s)" % self.text
+ return f"Suggestion({self.text})"
class AutoSuggest(metaclass=ABCMeta):
diff --git a/src/prompt_toolkit/buffer.py b/src/prompt_toolkit/buffer.py
index 6c006a258b..6ad3d2c0b7 100644
--- a/src/prompt_toolkit/buffer.py
+++ b/src/prompt_toolkit/buffer.py
@@ -119,19 +119,19 @@ def new_text_and_position(self) -> Tuple[str, int]:
"""
if self.complete_index is None:
return self.original_document.text, self.original_document.cursor_position
- else:
- original_text_before_cursor = self.original_document.text_before_cursor
- original_text_after_cursor = self.original_document.text_after_cursor
-
- c = self.completions[self.complete_index]
- if c.start_position == 0:
- before = original_text_before_cursor
- else:
- before = original_text_before_cursor[: c.start_position]
+ original_text_before_cursor = self.original_document.text_before_cursor
+ original_text_after_cursor = self.original_document.text_after_cursor
+
+ c = self.completions[self.complete_index]
+ before = (
+ original_text_before_cursor
+ if c.start_position == 0
+ else original_text_before_cursor[: c.start_position]
+ )
- new_text = before + c.text + original_text_after_cursor
- new_cursor_position = len(before) + len(c.text)
- return new_text, new_cursor_position
+ new_text = before + c.text + original_text_after_cursor
+ new_cursor_position = len(before) + len(c.text)
+ return new_text, new_cursor_position
@property
def current_completion(self) -> Optional["Completion"]:
@@ -313,11 +313,7 @@ def __init__(
self.reset(document=document)
def __repr__(self) -> str:
- if len(self.text) < 15:
- text = self.text
- else:
- text = self.text[:12] + "..."
-
+ text = self.text if len(self.text) < 15 else f"{self.text[:12]}..."
return f""
def reset(
@@ -449,15 +445,13 @@ def _set_text(self, value: str) -> bool:
working_lines[working_index] = value
# Return True when this text has been changed.
- if len(value) != len(original_value):
+ if len(value) != len(original_value) or value != original_value:
# For Python 2, it seems that when two strings have a different
# length and one is a prefix of the other, Python still scans
# character by character to see whether the strings are different.
# (Some benchmarking showed significant differences for big
# documents. >100,000 of lines.)
return True
- elif value != original_value:
- return True
return False
def _set_cursor_position(self, value: int) -> bool:
@@ -479,16 +473,12 @@ def text(self, value: str) -> None:
otherwise set a Document instead.)
"""
# Ensure cursor position remains within the size of the text.
- if self.cursor_position > len(value):
- self.cursor_position = len(value)
-
+ self.cursor_position = min(self.cursor_position, len(value))
# Don't allow editing of read-only buffers.
if self.read_only():
raise EditReadOnlyBuffer()
- changed = self._set_text(value)
-
- if changed:
+ if changed := self._set_text(value):
self._text_changed()
# Reset history search text.
@@ -509,14 +499,9 @@ def cursor_position(self, value: int) -> None:
assert isinstance(value, int)
# Ensure cursor position is within the size of the text.
- if value > len(self.text):
- value = len(self.text)
- if value < 0:
- value = 0
-
- changed = self._set_cursor_position(value)
-
- if changed:
+ value = min(value, len(self.text))
+ value = max(value, 0)
+ if changed := self._set_cursor_position(value):
self._cursor_position_changed()
@property
@@ -959,24 +944,22 @@ def start_history_lines_completion(self) -> None:
for i, string in enumerate(self._working_lines):
for j, l in enumerate(string.split("\n")):
l = l.strip()
- if l and l.startswith(current_line):
- # When a new line has been found.
- if l not in found_completions:
- found_completions.add(l)
+ if l and l.startswith(current_line) and l not in found_completions:
+ found_completions.add(l)
# Create completion.
- if i == self.working_index:
- display_meta = "Current, line %s" % (j + 1)
- else:
- display_meta = f"History {i + 1}, line {j + 1}"
-
- completions.append(
- Completion(
- text=l,
- start_position=-len(current_line),
- display_meta=display_meta,
- )
+ if i == self.working_index:
+ display_meta = f"Current, line {j + 1}"
+ else:
+ display_meta = f"History {i + 1}, line {j + 1}"
+
+ completions.append(
+ Completion(
+ text=l,
+ start_position=-len(current_line),
+ display_meta=display_meta,
)
+ )
self._set_completions(completions=completions[::-1])
self.go_to_completion(0)
@@ -1421,19 +1404,18 @@ def search_once(
working_index,
Document(document.text, document.cursor_position + new_index),
)
- else:
- # No match, go forward in the history. (Include len+1 to wrap around.)
- # (Here we should always include all cursor positions, because
- # it's a different line.)
- for i in range(working_index + 1, len(self._working_lines) + 1):
- i %= len(self._working_lines)
-
- document = Document(self._working_lines[i], 0)
- new_index = document.find(
- text, include_current_position=True, ignore_case=ignore_case
- )
- if new_index is not None:
- return (i, Document(document.text, new_index))
+ # No match, go forward in the history. (Include len+1 to wrap around.)
+ # (Here we should always include all cursor positions, because
+ # it's a different line.)
+ for i in range(working_index + 1, len(self._working_lines) + 1):
+ i %= len(self._working_lines)
+
+ document = Document(self._working_lines[i], 0)
+ new_index = document.find(
+ text, include_current_position=True, ignore_case=ignore_case
+ )
+ if new_index is not None:
+ return (i, Document(document.text, new_index))
else:
# Try find at the current input.
new_index = document.find_backwards(text, ignore_case=ignore_case)
@@ -1443,22 +1425,21 @@ def search_once(
working_index,
Document(document.text, document.cursor_position + new_index),
)
- else:
- # No match, go back in the history. (Include -1 to wrap around.)
- for i in range(working_index - 1, -2, -1):
- i %= len(self._working_lines)
+ # No match, go back in the history. (Include -1 to wrap around.)
+ for i in range(working_index - 1, -2, -1):
+ i %= len(self._working_lines)
- document = Document(
- self._working_lines[i], len(self._working_lines[i])
- )
- new_index = document.find_backwards(
- text, ignore_case=ignore_case
+ document = Document(
+ self._working_lines[i], len(self._working_lines[i])
+ )
+ new_index = document.find_backwards(
+ text, ignore_case=ignore_case
+ )
+ if new_index is not None:
+ return (
+ i,
+ Document(document.text, len(document.text) + new_index),
)
- if new_index is not None:
- return (
- i,
- Document(document.text, len(document.text) + new_index),
- )
return None
# Do 'count' search iterations.
@@ -1485,18 +1466,16 @@ def document_for_search(self, search_state: SearchState) -> Document:
if search_result is None:
return self.document
- else:
- working_index, cursor_position = search_result
+ working_index, cursor_position = search_result
# Keep selection, when `working_index` was not changed.
- if working_index == self.working_index:
- selection = self.selection_state
- else:
- selection = None
+ selection = (
+ self.selection_state if working_index == self.working_index else None
+ )
- return Document(
- self._working_lines[working_index], cursor_position, selection=selection
- )
+ return Document(
+ self._working_lines[working_index], cursor_position, selection=selection
+ )
def get_search_position(
self,
@@ -1515,9 +1494,8 @@ def get_search_position(
if search_result is None:
return self.cursor_position
- else:
- working_index, cursor_position = search_result
- return cursor_position
+ working_index, cursor_position = search_result
+ return cursor_position
def apply_search(
self,
@@ -1839,14 +1817,12 @@ async def async_suggestor() -> None:
suggestion = await self.auto_suggest.get_suggestion_async(self, document)
- # Set suggestion only if the text was not yet changed.
- if self.document == document:
- # Set suggestion and redraw interface.
- self.suggestion = suggestion
- self.on_suggestion_set.fire()
- else:
+ if self.document != document:
# Otherwise, restart thread.
raise _Retry
+ # Set suggestion and redraw interface.
+ self.suggestion = suggestion
+ self.on_suggestion_set.fire()
return async_suggestor
@@ -1868,15 +1844,8 @@ def validate_and_handle(self) -> None:
"""
Validate buffer and handle the accept action.
"""
- valid = self.validate(set_cursor=True)
-
- # When the validation succeeded, accept the input.
- if valid:
- if self.accept_handler:
- keep_text = self.accept_handler(self)
- else:
- keep_text = False
-
+ if valid := self.validate(set_cursor=True):
+ keep_text = self.accept_handler(self) if self.accept_handler else False
self.append_to_history()
if not keep_text:
@@ -1952,10 +1921,7 @@ def unindent(buffer: Buffer, from_row: int, to_row: int, count: int = 1) -> None
def transform(text: str) -> str:
remove = " " * count
- if text.startswith(remove):
- return text[len(remove) :]
- else:
- return text.lstrip()
+ return text[len(remove) :] if text.startswith(remove) else text.lstrip()
# Apply transformation.
new_text = buffer.transform_lines(line_range, transform)
@@ -1978,9 +1944,7 @@ def reshape_text(buffer: Buffer, from_row: int, to_row: int) -> None:
lines = buffer.text.splitlines(True)
lines_before = lines[:from_row]
lines_after = lines[to_row + 1 :]
- lines_to_reformat = lines[from_row : to_row + 1]
-
- if lines_to_reformat:
+ if lines_to_reformat := lines[from_row : to_row + 1]:
# Take indentation from the first line.
match = re.search(r"^\s*", lines_to_reformat[0])
length = match.end() if match else 0 # `match` can't be None, actually.
diff --git a/src/prompt_toolkit/clipboard/in_memory.py b/src/prompt_toolkit/clipboard/in_memory.py
index 1902e36a55..8d60ebb92f 100644
--- a/src/prompt_toolkit/clipboard/in_memory.py
+++ b/src/prompt_toolkit/clipboard/in_memory.py
@@ -35,10 +35,7 @@ def set_data(self, data: ClipboardData) -> None:
self._ring.pop()
def get_data(self) -> ClipboardData:
- if self._ring:
- return self._ring[0]
- else:
- return ClipboardData()
+ return self._ring[0] if self._ring else ClipboardData()
def rotate(self) -> None:
if self._ring:
diff --git a/src/prompt_toolkit/completion/base.py b/src/prompt_toolkit/completion/base.py
index 371c0ea6e5..505839e79f 100644
--- a/src/prompt_toolkit/completion/base.py
+++ b/src/prompt_toolkit/completion/base.py
@@ -79,13 +79,15 @@ def __repr__(self) -> str:
)
def __eq__(self, other: object) -> bool:
- if not isinstance(other, Completion):
- return False
return (
- self.text == other.text
- and self.start_position == other.start_position
- and self.display == other.display
- and self._display_meta == other._display_meta
+ (
+ self.text == other.text
+ and self.start_position == other.start_position
+ and self.display == other.display
+ and self._display_meta == other._display_meta
+ )
+ if isinstance(other, Completion)
+ else False
)
def __hash__(self) -> int:
@@ -381,16 +383,10 @@ def get_suffix(completion: Completion) -> str:
def _commonprefix(strings: Iterable[str]) -> str:
- # Similar to os.path.commonprefix
if not strings:
return ""
- else:
- s1 = min(strings)
- s2 = max(strings)
-
- for i, c in enumerate(s1):
- if c != s2[i]:
- return s1[:i]
+ s1 = min(strings)
+ s2 = max(strings)
- return s1
+ return next((s1[:i] for i, c in enumerate(s1) if c != s2[i]), s1)
diff --git a/src/prompt_toolkit/completion/filesystem.py b/src/prompt_toolkit/completion/filesystem.py
index 719eac6097..faa0948f02 100644
--- a/src/prompt_toolkit/completion/filesystem.py
+++ b/src/prompt_toolkit/completion/filesystem.py
@@ -53,9 +53,7 @@ def get_completions(
if self.expanduser:
text = os.path.expanduser(text)
- # Directories where to look.
- dirname = os.path.dirname(text)
- if dirname:
+ if dirname := os.path.dirname(text):
directories = [
os.path.dirname(os.path.join(p, text)) for p in self.get_paths()
]
@@ -70,9 +68,11 @@ def get_completions(
for directory in directories:
# Look for matches in this directory.
if os.path.isdir(directory):
- for filename in os.listdir(directory):
- if filename.startswith(prefix):
- filenames.append((directory, filename))
+ filenames.extend(
+ (directory, filename)
+ for filename in os.listdir(directory)
+ if filename.startswith(prefix)
+ )
# Sort
filenames = sorted(filenames, key=lambda k: k[1])
diff --git a/src/prompt_toolkit/completion/fuzzy_completer.py b/src/prompt_toolkit/completion/fuzzy_completer.py
index 627adc8738..85a94c3432 100644
--- a/src/prompt_toolkit/completion/fuzzy_completer.py
+++ b/src/prompt_toolkit/completion/fuzzy_completer.py
@@ -137,10 +137,10 @@ def _get_display(
# additional styling or characters).
return m.completion.display
- result: StyleAndTextTuples = []
+ result: StyleAndTextTuples = [
+ ("class:fuzzymatch.outside", word[: m.start_pos])
+ ]
- # Text before match.
- result.append(("class:fuzzymatch.outside", word[: m.start_pos]))
# The match itself.
characters = list(word_before_cursor)
diff --git a/src/prompt_toolkit/contrib/regular_languages/compiler.py b/src/prompt_toolkit/contrib/regular_languages/compiler.py
index fed78498c0..efa9f90080 100644
--- a/src/prompt_toolkit/contrib/regular_languages/compiler.py
+++ b/src/prompt_toolkit/contrib/regular_languages/compiler.py
@@ -96,7 +96,7 @@ def __init__(
counter = [0]
def create_group_func(node: Variable) -> str:
- name = "n%s" % counter[0]
+ name = f"n{counter[0]}"
self._group_names_to_nodes[name] = node.varname
counter[0] += 1
return name
@@ -153,13 +153,11 @@ def _transform(
def transform(node: Node) -> str:
# Turn `AnyNode` into an OR.
if isinstance(node, AnyNode):
- return "(?:%s)" % "|".join(transform(c) for c in node.children)
+ return f'(?:{"|".join((transform(c) for c in node.children))})'
- # Concatenate a `NodeSequence`
elif isinstance(node, NodeSequence):
return "".join(transform(c) for c in node.children)
- # For Regex and Lookahead nodes, just insert them literally.
elif isinstance(node, Regex):
return node.regex
@@ -167,14 +165,9 @@ def transform(node: Node) -> str:
before = "(?!" if node.negative else "(="
return before + transform(node.childnode) + ")"
- # A `Variable` wraps the children into a named group.
elif isinstance(node, Variable):
- return "(?P<{}>{})".format(
- create_group_func(node),
- transform(node.childnode),
- )
+ return f"(?P<{create_group_func(node)}>{transform(node.childnode)})"
- # `Repeat`.
elif isinstance(node, Repeat):
if node.max_repeat is None:
if node.min_repeat == 0:
@@ -187,11 +180,8 @@ def transform(node: Node) -> str:
("" if node.max_repeat is None else str(node.max_repeat)),
)
- return "(?:{}){}{}".format(
- transform(node.childnode),
- repeat_sign,
- ("" if node.greedy else "?"),
- )
+ return f'(?:{transform(node.childnode)}){repeat_sign}{"" if node.greedy else "?"}'
+
else:
raise TypeError(f"Got {node!r}")
@@ -263,11 +253,6 @@ def transform(node: Node) -> Iterable[str]:
r for c in children_without_variable for r in transform(c)
)
- # For a sequence, generate a pattern for each prefix that ends with
- # a variable + one pattern of the complete sequence.
- # (This is because, for autocompletion, we match the text before
- # the cursor, and completions are given for the variable that we
- # match right before the cursor.)
elif isinstance(node, NodeSequence):
# For all components in the sequence, compute prefix patterns,
# as well as full patterns.
@@ -295,9 +280,7 @@ def transform(node: Node) -> Iterable[str]:
# Start with complete patterns.
for i in range(len(node.children)):
- result.append("(?:")
- result.append(complete[i])
-
+ result.extend(("(?:", complete[i]))
# Add prefix patterns.
for i in range(len(node.children) - 1, -1, -1):
if variable_nodes[i]:
@@ -308,17 +291,15 @@ def transform(node: Node) -> Iterable[str]:
result.append("|(?:")
# If this yields multiple, we should yield all combinations.
assert len(prefixes[i]) == 1
- result.append(prefixes[i][0])
- result.append("))")
-
+ result.extend((prefixes[i][0], "))"))
yield "".join(result)
elif isinstance(node, Regex):
- yield "(?:%s)?" % node.regex
+ yield f"(?:{node.regex})?"
elif isinstance(node, Lookahead):
if node.negative:
- yield "(?!%s)" % cls._transform(node.childnode, create_group_func)
+ yield f"(?!{cls._transform(node.childnode, create_group_func)})"
else:
# Not sure what the correct semantics are in this case.
# (Probably it's not worth implementing this.)
@@ -340,16 +321,8 @@ def transform(node: Node) -> Iterable[str]:
yield from transform(node.childnode)
else:
for c_str in transform(node.childnode):
- if node.max_repeat:
- repeat_sign = "{,%i}" % (node.max_repeat - 1)
- else:
- repeat_sign = "*"
- yield "(?:{}){}{}{}".format(
- prefix,
- repeat_sign,
- ("" if node.greedy else "?"),
- c_str,
- )
+ repeat_sign = "{,%i}" % (node.max_repeat - 1) if node.max_repeat else "*"
+ yield f'(?:{prefix}){repeat_sign}{"" if node.greedy else "?"}{c_str}'
else:
raise TypeError("Got %r" % node)
@@ -364,9 +337,7 @@ def match(self, string: str) -> Optional["Match"]:
:param string: The input string.
"""
- m = self._re.match(string)
-
- if m:
+ if m := self._re.match(string):
return Match(
string, [(self._re, m)], self._group_names_to_nodes, self.unescape_funcs
)
@@ -469,9 +440,11 @@ def trailing_input(self) -> Optional["MatchVariable"]:
# Find all regex group for the name _INVALID_TRAILING_INPUT.
for r, re_match in self._re_matches:
- for group_name, group_index in r.groupindex.items():
- if group_name == _INVALID_TRAILING_INPUT:
- slices.append(re_match.regs[group_index])
+ slices.extend(
+ re_match.regs[group_index]
+ for group_name, group_index in r.groupindex.items()
+ if group_name == _INVALID_TRAILING_INPUT
+ )
# Take the smallest part. (Smaller trailing text means that a larger input has
# been matched, so that is better.)
@@ -499,10 +472,7 @@ def __init__(self, tuples: List[Tuple[str, str, Tuple[int, int]]]) -> None:
self._tuples = tuples
def __repr__(self) -> str:
- return "{}({})".format(
- self.__class__.__name__,
- ", ".join(f"{k}={v!r}" for k, v, _ in self._tuples),
- )
+ return f'{self.__class__.__name__}({", ".join((f"{k}={v!r}" for k, v, _ in self._tuples))})'
def get(self, key: str, default: Optional[str] = None) -> Optional[str]:
items = self.getall(key)
diff --git a/src/prompt_toolkit/contrib/regular_languages/completion.py b/src/prompt_toolkit/contrib/regular_languages/completion.py
index 3cebcc03f6..5d0a0651c1 100644
--- a/src/prompt_toolkit/contrib/regular_languages/completion.py
+++ b/src/prompt_toolkit/contrib/regular_languages/completion.py
@@ -33,15 +33,11 @@ def __init__(
def get_completions(
self, document: Document, complete_event: CompleteEvent
) -> Iterable[Completion]:
- m = self.compiled_grammar.match_prefix(document.text_before_cursor)
-
- if m:
- completions = self._remove_duplicates(
+ if m := self.compiled_grammar.match_prefix(document.text_before_cursor):
+ yield from self._remove_duplicates(
self._get_completions_for_match(m, complete_event)
)
- yield from completions
-
def _get_completions_for_match(
self, match: Match, complete_event: CompleteEvent
) -> Iterable[Completion]:
@@ -54,9 +50,7 @@ def _get_completions_for_match(
varname = match_variable.varname
start = match_variable.start
- completer = self.completers.get(varname)
-
- if completer:
+ if completer := self.completers.get(varname):
text = match_variable.value
# Unwrap text.
diff --git a/src/prompt_toolkit/contrib/regular_languages/lexer.py b/src/prompt_toolkit/contrib/regular_languages/lexer.py
index 1ddeede802..15dc4a38d9 100644
--- a/src/prompt_toolkit/contrib/regular_languages/lexer.py
+++ b/src/prompt_toolkit/contrib/regular_languages/lexer.py
@@ -43,42 +43,33 @@ def __init__(
self.lexers = lexers or {}
def _get_text_fragments(self, text: str) -> StyleAndTextTuples:
- m = self.compiled_grammar.match_prefix(text)
-
- if m:
- characters: StyleAndTextTuples = [(self.default_style, c) for c in text]
-
- for v in m.variables():
- # If we have a `Lexer` instance for this part of the input.
- # Tokenize recursively and apply tokens.
- lexer = self.lexers.get(v.varname)
-
- if lexer:
- document = Document(text[v.start : v.stop])
- lexer_tokens_for_line = lexer.lex_document(document)
- text_fragments: StyleAndTextTuples = []
- for i in range(len(document.lines)):
- text_fragments.extend(lexer_tokens_for_line(i))
- text_fragments.append(("", "\n"))
- if text_fragments:
- text_fragments.pop()
-
- i = v.start
- for t, s, *_ in text_fragments:
- for c in s:
- if characters[i][0] == self.default_style:
- characters[i] = (t, characters[i][1])
- i += 1
-
- # Highlight trailing input.
- trailing_input = m.trailing_input()
- if trailing_input:
- for i in range(trailing_input.start, trailing_input.stop):
- characters[i] = ("class:trailing-input", characters[i][1])
-
- return characters
- else:
+ if not (m := self.compiled_grammar.match_prefix(text)):
return [("", text)]
+ characters: StyleAndTextTuples = [(self.default_style, c) for c in text]
+
+ for v in m.variables():
+ if lexer := self.lexers.get(v.varname):
+ document = Document(text[v.start : v.stop])
+ lexer_tokens_for_line = lexer.lex_document(document)
+ text_fragments: StyleAndTextTuples = []
+ for i in range(len(document.lines)):
+ text_fragments.extend(lexer_tokens_for_line(i))
+ text_fragments.append(("", "\n"))
+ if text_fragments:
+ text_fragments.pop()
+
+ i = v.start
+ for t, s, *_ in text_fragments:
+ for _ in s:
+ if characters[i][0] == self.default_style:
+ characters[i] = (t, characters[i][1])
+ i += 1
+
+ if trailing_input := m.trailing_input():
+ for i in range(trailing_input.start, trailing_input.stop):
+ characters[i] = ("class:trailing-input", characters[i][1])
+
+ return characters
def lex_document(self, document: Document) -> Callable[[int], StyleAndTextTuples]:
lines = list(split_lines(self._get_text_fragments(document.text)))
diff --git a/src/prompt_toolkit/contrib/regular_languages/regex_parser.py b/src/prompt_toolkit/contrib/regular_languages/regex_parser.py
index 87e39d498c..5e8745a272 100644
--- a/src/prompt_toolkit/contrib/regular_languages/regex_parser.py
+++ b/src/prompt_toolkit/contrib/regular_languages/regex_parser.py
@@ -180,8 +180,7 @@ def tokenize_regex(input: str) -> List[str]:
tokens = []
while input:
- m = p.match(input)
- if m:
+ if m := p.match(input):
token, input = input[: m.end()], input[m.end() :]
if not token.isspace():
tokens.append(token)
@@ -200,10 +199,7 @@ def parse_regex(regex_tokens: List[str]) -> Node:
def wrap(lst: List[Node]) -> Node:
"""Turn list into sequence when it contains several items."""
- if len(lst) == 1:
- return lst[0]
- else:
- return NodeSequence(lst)
+ return lst[0] if len(lst) == 1 else NodeSequence(lst)
def _parse() -> Node:
or_list: List[List[Node]] = []
@@ -212,9 +208,8 @@ def _parse() -> Node:
def wrapped_result() -> Node:
if or_list == []:
return wrap(result)
- else:
- or_list.append(result)
- return AnyNode([wrap(i) for i in or_list])
+ or_list.append(result)
+ return AnyNode([wrap(i) for i in or_list])
while tokens:
t = tokens.pop()
diff --git a/src/prompt_toolkit/contrib/regular_languages/validation.py b/src/prompt_toolkit/contrib/regular_languages/validation.py
index 71d3434035..d27e8de526 100644
--- a/src/prompt_toolkit/contrib/regular_languages/validation.py
+++ b/src/prompt_toolkit/contrib/regular_languages/validation.py
@@ -31,30 +31,22 @@ def __init__(
self.validators = validators
def validate(self, document: Document) -> None:
- # Parse input document.
- # We use `match`, not `match_prefix`, because for validation, we want
- # the actual, unambiguous interpretation of the input.
- m = self.compiled_grammar.match(document.text)
-
- if m:
- for v in m.variables():
- validator = self.validators.get(v.varname)
-
- if validator:
- # Unescape text.
- unwrapped_text = self.compiled_grammar.unescape(v.varname, v.value)
-
- # Create a document, for the completions API (text/cursor_position)
- inner_document = Document(unwrapped_text, len(unwrapped_text))
-
- try:
- validator.validate(inner_document)
- except ValidationError as e:
- raise ValidationError(
- cursor_position=v.start + e.cursor_position,
- message=e.message,
- ) from e
- else:
+ if not (m := self.compiled_grammar.match(document.text)):
raise ValidationError(
cursor_position=len(document.text), message="Invalid command"
)
+ for v in m.variables():
+ if validator := self.validators.get(v.varname):
+ # Unescape text.
+ unwrapped_text = self.compiled_grammar.unescape(v.varname, v.value)
+
+ # Create a document, for the completions API (text/cursor_position)
+ inner_document = Document(unwrapped_text, len(unwrapped_text))
+
+ try:
+ validator.validate(inner_document)
+ except ValidationError as e:
+ raise ValidationError(
+ cursor_position=v.start + e.cursor_position,
+ message=e.message,
+ ) from e
diff --git a/src/prompt_toolkit/contrib/ssh/server.py b/src/prompt_toolkit/contrib/ssh/server.py
index 98f3b68177..f2c5f1a24a 100644
--- a/src/prompt_toolkit/contrib/ssh/server.py
+++ b/src/prompt_toolkit/contrib/ssh/server.py
@@ -41,10 +41,10 @@ def write(s, data: str) -> None:
except BrokenPipeError:
pass # Channel not open for sending.
- def isatty(s) -> bool:
+ def isatty(self) -> bool:
return True
- def flush(s) -> None:
+ def flush(self) -> None:
pass
@property
@@ -60,9 +60,8 @@ def _get_size(self) -> Size:
"""
if self._chan is None:
return Size(rows=20, columns=79)
- else:
- width, height, pixwidth, pixheight = self._chan.get_terminal_size()
- return Size(rows=height, columns=width)
+ width, height, pixwidth, pixheight = self._chan.get_terminal_size()
+ return Size(rows=height, columns=width)
def connection_made(self, chan: Any) -> None:
self._chan = chan
diff --git a/src/prompt_toolkit/contrib/telnet/protocol.py b/src/prompt_toolkit/contrib/telnet/protocol.py
index 68f3639880..fb627e40e6 100644
--- a/src/prompt_toolkit/contrib/telnet/protocol.py
+++ b/src/prompt_toolkit/contrib/telnet/protocol.py
@@ -131,7 +131,7 @@ def ttype(self, data: bytes) -> None:
"""
Received terminal type.
"""
- subcmd, data = data[0:1], data[1:]
+ subcmd, data = data[:1], data[1:]
if subcmd == IS:
ttype = data.decode("ascii")
self.ttype_received_callback(ttype)
@@ -142,7 +142,7 @@ def negotiate(self, data: bytes) -> None:
"""
Got negotiate data.
"""
- command, payload = data[0:1], data[1:]
+ command, payload = data[:1], data[1:]
if command == NAWS:
self.naws(payload)
diff --git a/src/prompt_toolkit/contrib/telnet/server.py b/src/prompt_toolkit/contrib/telnet/server.py
index b6248cd3e5..98be17f2cd 100644
--- a/src/prompt_toolkit/contrib/telnet/server.py
+++ b/src/prompt_toolkit/contrib/telnet/server.py
@@ -181,8 +181,7 @@ async def run_application(self) -> None:
"""
def handle_incoming_data() -> None:
- data = self.conn.recv(1024)
- if data:
+ if data := self.conn.recv(1024):
self.feed(data)
else:
# Connection closed by client.
@@ -364,7 +363,7 @@ async def run() -> None:
# Unhandled control-c propagated by a prompt.
logger.info("Unhandled KeyboardInterrupt in telnet application.")
except BaseException as e:
- print("Got %s" % type(e).__name__, e)
+ print(f"Got {type(e).__name__}", e)
import traceback
traceback.print_exc()
diff --git a/src/prompt_toolkit/document.py b/src/prompt_toolkit/document.py
index 1984155205..91ea8e2d0d 100644
--- a/src/prompt_toolkit/document.py
+++ b/src/prompt_toolkit/document.py
@@ -140,13 +140,14 @@ def __repr__(self) -> str:
return f"{self.__class__.__name__}({self.text!r}, {self.cursor_position!r})"
def __eq__(self, other: object) -> bool:
- if not isinstance(other, Document):
- return False
-
return (
- self.text == other.text
- and self.cursor_position == other.cursor_position
- and self.selection == other.selection
+ (
+ self.text == other.text
+ and self.cursor_position == other.cursor_position
+ and self.selection == other.selection
+ )
+ if isinstance(other, Document)
+ else False
)
@property
@@ -398,10 +399,7 @@ def find(
try:
for i, match in enumerate(iterator):
if i + 1 == count:
- if include_current_position:
- return match.start(0)
- else:
- return match.start(0) + 1
+ return match.start(0) if include_current_position else match.start(0) + 1
except StopIteration:
pass
return None
@@ -604,11 +602,7 @@ def find_next_word_ending(
if i + 1 == count:
value = match.end(1)
- if include_current_position:
- return value
- else:
- return value + 1
-
+ return value if include_current_position else value + 1
except StopIteration:
pass
return None
@@ -771,11 +765,7 @@ def find_enclosing_bracket_right(
if self.current_char == right_ch:
return 0
- if end_pos is None:
- end_pos = len(self.text)
- else:
- end_pos = min(len(self.text), end_pos)
-
+ end_pos = len(self.text) if end_pos is None else min(len(self.text), end_pos)
stack = 1
# Look forward.
@@ -804,11 +794,7 @@ def find_enclosing_bracket_left(
if self.current_char == left_ch:
return 0
- if start_pos is None:
- start_pos = 0
- else:
- start_pos = max(0, start_pos)
-
+ start_pos = 0 if start_pos is None else max(0, start_pos)
stack = 1
# Look backward.
@@ -855,15 +841,14 @@ def get_end_of_document_position(self) -> int:
def get_start_of_line_position(self, after_whitespace: bool = False) -> int:
"""Relative position for the start of this line."""
- if after_whitespace:
- current_line = self.current_line
- return (
- len(current_line)
- - len(current_line.lstrip())
- - self.cursor_position_col
- )
- else:
+ if not after_whitespace:
return -len(self.current_line_before_cursor)
+ current_line = self.current_line
+ return (
+ len(current_line)
+ - len(current_line.lstrip())
+ - self.cursor_position_col
+ )
def get_end_of_line_position(self) -> int:
"""Relative position for the end of this line."""
@@ -917,46 +902,47 @@ def selection_ranges(self) -> Iterable[Tuple[int, int]]:
This will return zero ranges, like (8,8) for empty lines in a block
selection.
"""
- if self.selection:
- from_, to = sorted(
- [self.cursor_position, self.selection.original_cursor_position]
- )
-
- if self.selection.type == SelectionType.BLOCK:
- from_line, from_column = self.translate_index_to_position(from_)
- to_line, to_column = self.translate_index_to_position(to)
- from_column, to_column = sorted([from_column, to_column])
- lines = self.lines
-
- if vi_mode():
- to_column += 1
-
- for l in range(from_line, to_line + 1):
- line_length = len(lines[l])
+ if not self.selection:
+ return
+ from_, to = sorted(
+ [self.cursor_position, self.selection.original_cursor_position]
+ )
- if from_column <= line_length:
- yield (
- self.translate_row_col_to_index(l, from_column),
- self.translate_row_col_to_index(
- l, min(line_length, to_column)
- ),
- )
- else:
- # In case of a LINES selection, go to the start/end of the lines.
- if self.selection.type == SelectionType.LINES:
- from_ = max(0, self.text.rfind("\n", 0, from_) + 1)
+ if self.selection.type == SelectionType.BLOCK:
+ from_line, from_column = self.translate_index_to_position(from_)
+ to_line, to_column = self.translate_index_to_position(to)
+ from_column, to_column = sorted([from_column, to_column])
+ lines = self.lines
+
+ if vi_mode():
+ to_column += 1
+
+ for l in range(from_line, to_line + 1):
+ line_length = len(lines[l])
+
+ if from_column <= line_length:
+ yield (
+ self.translate_row_col_to_index(l, from_column),
+ self.translate_row_col_to_index(
+ l, min(line_length, to_column)
+ ),
+ )
+ else:
+ # In case of a LINES selection, go to the start/end of the lines.
+ if self.selection.type == SelectionType.LINES:
+ from_ = max(0, self.text.rfind("\n", 0, from_) + 1)
- if self.text.find("\n", to) >= 0:
- to = self.text.find("\n", to)
- else:
- to = len(self.text) - 1
+ if self.text.find("\n", to) >= 0:
+ to = self.text.find("\n", to)
+ else:
+ to = len(self.text) - 1
- # In Vi mode, the upper boundary is always included. For Emacs,
- # that's not the case.
- if vi_mode():
- to += 1
+ # In Vi mode, the upper boundary is always included. For Emacs,
+ # that's not the case.
+ if vi_mode():
+ to += 1
- yield from_, to
+ yield from_, to
def selection_range_at_line(self, row: int) -> Optional[Tuple[int, int]]:
"""
@@ -1014,35 +1000,34 @@ def cut_selection(self) -> Tuple["Document", ClipboardData]:
document represents the new document when the selection is cut, and the
clipboard data, represents whatever has to be put on the clipboard.
"""
- if self.selection:
- cut_parts = []
- remaining_parts = []
- new_cursor_position = self.cursor_position
+ if not self.selection:
+ return self, ClipboardData("")
+ cut_parts = []
+ remaining_parts = []
+ new_cursor_position = self.cursor_position
- last_to = 0
- for from_, to in self.selection_ranges():
- if last_to == 0:
- new_cursor_position = from_
+ last_to = 0
+ for from_, to in self.selection_ranges():
+ if last_to == 0:
+ new_cursor_position = from_
- remaining_parts.append(self.text[last_to:from_])
- cut_parts.append(self.text[from_:to])
- last_to = to
+ remaining_parts.append(self.text[last_to:from_])
+ cut_parts.append(self.text[from_:to])
+ last_to = to
- remaining_parts.append(self.text[last_to:])
+ remaining_parts.append(self.text[last_to:])
- cut_text = "\n".join(cut_parts)
- remaining_text = "".join(remaining_parts)
+ cut_text = "\n".join(cut_parts)
+ remaining_text = "".join(remaining_parts)
- # In case of a LINES selection, don't include the trailing newline.
- if self.selection.type == SelectionType.LINES and cut_text.endswith("\n"):
- cut_text = cut_text[:-1]
+ # In case of a LINES selection, don't include the trailing newline.
+ if self.selection.type == SelectionType.LINES and cut_text.endswith("\n"):
+ cut_text = cut_text[:-1]
- return (
- Document(text=remaining_text, cursor_position=new_cursor_position),
- ClipboardData(cut_text, self.selection.type),
- )
- else:
- return self, ClipboardData("")
+ return (
+ Document(text=remaining_text, cursor_position=new_cursor_position),
+ ClipboardData(cut_text, self.selection.type),
+ )
def paste_clipboard_data(
self,
@@ -1080,13 +1065,11 @@ def paste_clipboard_data(
l = self.cursor_position_row
if before:
lines = self.lines[:l] + [data.text] * count + self.lines[l:]
- new_text = "\n".join(lines)
new_cursor_position = len("".join(self.lines[:l])) + l
else:
lines = self.lines[: l + 1] + [data.text] * count + self.lines[l + 1 :]
new_cursor_position = len("".join(self.lines[: l + 1])) + l + 1
- new_text = "\n".join(lines)
-
+ new_text = "\n".join(lines)
elif data.type == SelectionType.BLOCK:
lines = self.lines[:]
start_line = self.cursor_position_row
diff --git a/src/prompt_toolkit/eventloop/async_context_manager.py b/src/prompt_toolkit/eventloop/async_context_manager.py
index 39146165a0..3ee735682f 100644
--- a/src/prompt_toolkit/eventloop/async_context_manager.py
+++ b/src/prompt_toolkit/eventloop/async_context_manager.py
@@ -89,9 +89,11 @@ async def __aexit__(self, typ, value, traceback):
# have this behavior). But do this only if the exception wrapped
# by the RuntimeError is actully Stop(Async)Iteration (see
# issue29692).
- if isinstance(value, (StopIteration, StopAsyncIteration)):
- if exc.__cause__ is value:
- return False
+ if (
+ isinstance(value, (StopIteration, StopAsyncIteration))
+ and exc.__cause__ is value
+ ):
+ return False
raise
except BaseException as exc:
if exc is not value:
diff --git a/src/prompt_toolkit/eventloop/inputhook.py b/src/prompt_toolkit/eventloop/inputhook.py
index 05d298117e..1a3d830a2b 100644
--- a/src/prompt_toolkit/eventloop/inputhook.py
+++ b/src/prompt_toolkit/eventloop/inputhook.py
@@ -54,8 +54,7 @@ def new_eventloop_with_inputhook(
Create a new event loop with the given inputhook.
"""
selector = InputHookSelector(selectors.DefaultSelector(), inputhook)
- loop = asyncio.SelectorEventLoop(selector)
- return loop
+ return asyncio.SelectorEventLoop(selector)
def set_eventloop_with_inputhook(
diff --git a/src/prompt_toolkit/eventloop/utils.py b/src/prompt_toolkit/eventloop/utils.py
index 2e5a05e838..afa4cf92e6 100644
--- a/src/prompt_toolkit/eventloop/utils.py
+++ b/src/prompt_toolkit/eventloop/utils.py
@@ -90,8 +90,7 @@ def get_traceback_from_context(context: Dict[str, Any]) -> Optional[TracebackTyp
"""
Get the traceback object from the context.
"""
- exception = context.get("exception")
- if exception:
+ if exception := context.get("exception"):
if hasattr(exception, "__traceback__"):
return cast(TracebackType, exception.__traceback__)
else:
diff --git a/src/prompt_toolkit/eventloop/win32.py b/src/prompt_toolkit/eventloop/win32.py
index fbc02d493a..9639ccd1e2 100644
--- a/src/prompt_toolkit/eventloop/win32.py
+++ b/src/prompt_toolkit/eventloop/win32.py
@@ -52,10 +52,7 @@ def wait_for_handles(
len(handle_array), handle_array, BOOL(False), DWORD(timeout)
)
- if ret == WAIT_TIMEOUT:
- return None
- else:
- return handles[ret]
+ return None if ret == WAIT_TIMEOUT else handles[ret]
def create_win32_event() -> HANDLE:
diff --git a/src/prompt_toolkit/filters/app.py b/src/prompt_toolkit/filters/app.py
index dcc3fc0c6e..668c80b214 100644
--- a/src/prompt_toolkit/filters/app.py
+++ b/src/prompt_toolkit/filters/app.py
@@ -87,10 +87,10 @@ def test() -> bool:
# focused.
current_window = get_app().layout.current_window
- for c in walk(cast(Container, value)):
- if isinstance(c, Window) and c == current_window:
- return True
- return False
+ return any(
+ isinstance(c, Window) and c == current_window
+ for c in walk(cast(Container, value))
+ )
@Condition
def has_focus_filter() -> bool:
diff --git a/src/prompt_toolkit/formatted_text/ansi.py b/src/prompt_toolkit/formatted_text/ansi.py
index 2a30b09c21..d68272cb83 100644
--- a/src/prompt_toolkit/formatted_text/ansi.py
+++ b/src/prompt_toolkit/formatted_text/ansi.py
@@ -98,7 +98,6 @@ def _parse_corot(self) -> Generator[None, str, None]:
if char.isdigit():
current += char
- # Eval number
else:
# Limit and save number value
params.append(min(int(current or 0), 9999))
@@ -107,16 +106,14 @@ def _parse_corot(self) -> Generator[None, str, None]:
if char == ";":
current = ""
- # Check and evaluate color codes
elif char == "m":
# Set attributes and token.
self._select_graphic_rendition(params)
style = self._create_style_string()
break
- # Check and evaluate cursor forward
elif char == "C":
- for i in range(params[0]):
+ for _ in range(params[0]):
# add using current style
formatted_text.append((style, " "))
break
@@ -137,11 +134,7 @@ def _select_graphic_rendition(self, attrs: List[int]) -> None:
"""
Taken a list of graphics attributes and apply changes.
"""
- if not attrs:
- attrs = [0]
- else:
- attrs = list(attrs[::-1])
-
+ attrs = list(attrs[::-1]) if attrs else [0]
while attrs:
attr = attrs.pop()
@@ -151,8 +144,6 @@ def _select_graphic_rendition(self, attrs: List[int]) -> None:
self._bgcolor = _bg_colors[attr]
elif attr == 1:
self._bold = True
- # elif attr == 2:
- # self._faint = True
elif attr == 3:
self._italic = True
elif attr == 4:
@@ -197,7 +188,7 @@ def _select_graphic_rendition(self, attrs: List[int]) -> None:
n = attrs.pop()
# 256 colors.
- if n == 5 and len(attrs) >= 1:
+ if n == 5 and attrs:
if attr == 38:
m = attrs.pop()
self._color = _256_colors.get(m)
@@ -229,7 +220,7 @@ def _create_style_string(self) -> str:
if self._color:
result.append(self._color)
if self._bgcolor:
- result.append("bg:" + self._bgcolor)
+ result.append(f"bg:{self._bgcolor}")
if self._bold:
result.append("bold")
if self._underline:
@@ -276,10 +267,10 @@ def __mod__(self, value: object) -> "ANSI":
_bg_colors = {v: k for k, v in BG_ANSI_COLORS.items()}
# Mapping of the escape codes for 256colors to their 'ffffff' value.
-_256_colors = {}
-
-for i, (r, g, b) in enumerate(_256_colors_table.colors):
- _256_colors[i] = f"#{r:02x}{g:02x}{b:02x}"
+_256_colors = {
+ i: f"#{r:02x}{g:02x}{b:02x}"
+ for i, (r, g, b) in enumerate(_256_colors_table.colors)
+}
def ansi_escape(text: object) -> str:
diff --git a/src/prompt_toolkit/formatted_text/base.py b/src/prompt_toolkit/formatted_text/base.py
index e88c5935a5..5d1bd281f8 100644
--- a/src/prompt_toolkit/formatted_text/base.py
+++ b/src/prompt_toolkit/formatted_text/base.py
@@ -89,16 +89,14 @@ def to_formatted_text(
if style:
result = cast(
StyleAndTextTuples,
- [(style + " " + item_style, *rest) for item_style, *rest in result],
+ [(f"{style} {item_style}", *rest) for item_style, *rest in result],
)
+
# Make sure the result is wrapped in a `FormattedText`. Among other
# reasons, this is important for `print_formatted_text` to work correctly
# and distinguish between lists and formatted text.
- if isinstance(result, FormattedText):
- return result
- else:
- return FormattedText(result)
+ return result if isinstance(result, FormattedText) else FormattedText(result)
def is_formatted_text(value: object) -> "TypeGuard[AnyFormattedText]":
@@ -128,7 +126,7 @@ def __pt_formatted_text__(self) -> StyleAndTextTuples:
return self
def __repr__(self) -> str:
- return "FormattedText(%s)" % super().__repr__()
+ return f"FormattedText({super().__repr__()})"
class Template:
diff --git a/src/prompt_toolkit/formatted_text/html.py b/src/prompt_toolkit/formatted_text/html.py
index 0af2b18b57..aa53f3d153 100644
--- a/src/prompt_toolkit/formatted_text/html.py
+++ b/src/prompt_toolkit/formatted_text/html.py
@@ -44,9 +44,9 @@ def get_current_style() -> str:
parts.append("class:" + ",".join(name_stack))
if fg_stack:
- parts.append("fg:" + fg_stack[-1])
+ parts.append(f"fg:{fg_stack[-1]}")
if bg_stack:
- parts.append("bg:" + bg_stack[-1])
+ parts.append(f"bg:{bg_stack[-1]}")
return " ".join(parts)
def process_node(node: Any) -> None:
@@ -63,13 +63,10 @@ def process_node(node: Any) -> None:
fg = bg = ""
for k, v in child.attributes.items():
- if k == "fg":
- fg = v
if k == "bg":
bg = v
- if k == "color":
- fg = v # Alias for 'fg'.
-
+ elif k in ["fg", "color"]:
+ fg = v
# Check for spaces in attributes. This would result in
# invalid style strings otherwise.
if " " in fg:
diff --git a/src/prompt_toolkit/formatted_text/pygments.py b/src/prompt_toolkit/formatted_text/pygments.py
index dd16f0efbe..1ac32e4324 100644
--- a/src/prompt_toolkit/formatted_text/pygments.py
+++ b/src/prompt_toolkit/formatted_text/pygments.py
@@ -22,9 +22,7 @@ def __init__(self, token_list: List[Tuple["Token", str]]) -> None:
self.token_list = token_list
def __pt_formatted_text__(self) -> StyleAndTextTuples:
- result: StyleAndTextTuples = []
-
- for token, text in self.token_list:
- result.append(("class:" + pygments_token_to_classname(token), text))
-
- return result
+ return [
+ (f"class:{pygments_token_to_classname(token)}", text)
+ for token, text in self.token_list
+ ]
diff --git a/src/prompt_toolkit/history.py b/src/prompt_toolkit/history.py
index 987d7175de..3e8f21d3ee 100644
--- a/src/prompt_toolkit/history.py
+++ b/src/prompt_toolkit/history.py
@@ -225,10 +225,7 @@ class InMemoryHistory(History):
def __init__(self, history_strings: Optional[Sequence[str]] = None) -> None:
super().__init__()
# Emulating disk storage.
- if history_strings is None:
- self._storage = []
- else:
- self._storage = list(history_strings)
+ self._storage = [] if history_strings is None else list(history_strings)
def load_history_strings(self) -> Iterable[str]:
yield from self._storage[::-1]
diff --git a/src/prompt_toolkit/input/ansi_escape_sequences.py b/src/prompt_toolkit/input/ansi_escape_sequences.py
index 2e6c5b9b28..59238952c5 100644
--- a/src/prompt_toolkit/input/ansi_escape_sequences.py
+++ b/src/prompt_toolkit/input/ansi_escape_sequences.py
@@ -333,9 +333,8 @@ def _get_reverse_ansi_sequences() -> Dict[Keys, str]:
result: Dict[Keys, str] = {}
for sequence, key in ANSI_SEQUENCES.items():
- if not isinstance(key, tuple):
- if key not in result:
- result[key] = sequence
+ if not isinstance(key, tuple) and key not in result:
+ result[key] = sequence
return result
diff --git a/src/prompt_toolkit/input/base.py b/src/prompt_toolkit/input/base.py
index 313622de5a..ad7e6f3d5e 100644
--- a/src/prompt_toolkit/input/base.py
+++ b/src/prompt_toolkit/input/base.py
@@ -114,7 +114,7 @@ def fileno(self) -> int:
raise NotImplementedError
def typeahead_hash(self) -> str:
- return "dummy-%s" % id(self)
+ return f"dummy-{id(self)}"
def read_keys(self) -> List[KeyPress]:
return []
diff --git a/src/prompt_toolkit/input/posix_pipe.py b/src/prompt_toolkit/input/posix_pipe.py
index 1e7dec77fd..9947dcad6b 100644
--- a/src/prompt_toolkit/input/posix_pipe.py
+++ b/src/prompt_toolkit/input/posix_pipe.py
@@ -66,7 +66,7 @@ def __init__(self, _pipe: _Pipe, _text: str = "") -> None:
class Stdin:
encoding = "utf-8"
- def isatty(stdin) -> bool:
+ def isatty(self) -> bool:
return True
def fileno(stdin) -> int:
diff --git a/src/prompt_toolkit/input/vt100.py b/src/prompt_toolkit/input/vt100.py
index 45ce37208a..7539a7c522 100644
--- a/src/prompt_toolkit/input/vt100.py
+++ b/src/prompt_toolkit/input/vt100.py
@@ -289,10 +289,8 @@ def _patch_iflag(cls, attrs: int) -> int:
def __exit__(self, *a: object) -> None:
if self.attrs_before is not None:
- try:
+ with contextlib.suppress(termios.error):
termios.tcsetattr(self.fileno, termios.TCSANOW, self.attrs_before)
- except termios.error:
- pass
# # Put the terminal in application mode.
# self._stdout.write('\x1b[?1h')
diff --git a/src/prompt_toolkit/input/vt100_parser.py b/src/prompt_toolkit/input/vt100_parser.py
index 3ee1e14fdd..f2d596f147 100644
--- a/src/prompt_toolkit/input/vt100_parser.py
+++ b/src/prompt_toolkit/input/vt100_parser.py
@@ -145,27 +145,26 @@ def _input_parser_generator(self) -> Generator[None, Union[str, _Flush], None]:
match = self._get_match(prefix)
# Exact matches found, call handlers..
- if (flush or not is_prefix_of_longer_match) and match:
- self._call_handler(match, prefix)
- prefix = ""
-
- # No exact match found.
- elif (flush or not is_prefix_of_longer_match) and not match:
- found = False
- retry = True
-
- # Loop over the input, try the longest match first and
- # shift.
- for i in range(len(prefix), 0, -1):
- match = self._get_match(prefix[:i])
- if match:
- self._call_handler(match, prefix[:i])
- prefix = prefix[i:]
- found = True
-
- if not found:
- self._call_handler(prefix[0], prefix[0])
- prefix = prefix[1:]
+ if (flush or not is_prefix_of_longer_match):
+ if match:
+ self._call_handler(match, prefix)
+ prefix = ""
+
+ else:
+ found = False
+ retry = True
+
+ # Loop over the input, try the longest match first and
+ # shift.
+ for i in range(len(prefix), 0, -1):
+ if match := self._get_match(prefix[:i]):
+ self._call_handler(match, prefix[:i])
+ prefix = prefix[i:]
+ found = True
+
+ if not found:
+ self._call_handler(prefix[0], prefix[0])
+ prefix = prefix[1:]
def _call_handler(
self, key: Union[str, Keys, Tuple[Keys, ...]], insert_text: str
@@ -180,12 +179,11 @@ def _call_handler(
# multiple times).
for i, k in enumerate(key):
self._call_handler(k, insert_text if i == 0 else "")
+ elif key == Keys.BracketedPaste:
+ self._in_bracketed_paste = True
+ self._paste_buffer = ""
else:
- if key == Keys.BracketedPaste:
- self._in_bracketed_paste = True
- self._paste_buffer = ""
- else:
- self.feed_key_callback(KeyPress(key, insert_text))
+ self.feed_key_callback(KeyPress(key, insert_text))
def feed(self, data: str) -> None:
"""
diff --git a/src/prompt_toolkit/input/win32.py b/src/prompt_toolkit/input/win32.py
index db3fa2badd..13cb3788ff 100644
--- a/src/prompt_toolkit/input/win32.py
+++ b/src/prompt_toolkit/input/win32.py
@@ -404,15 +404,14 @@ def _event_to_key_presses(self, ev: KEY_EVENT_RECORD) -> List[KeyPress]:
if u_char == "\x00":
if ev.VirtualKeyCode in self.keycodes:
result = KeyPress(self.keycodes[ev.VirtualKeyCode], "")
+ elif ascii_char in self.mappings:
+ if self.mappings[ascii_char] == Keys.ControlJ:
+ u_char = (
+ "\n" # Windows sends \n, turn into \r for unix compatibility.
+ )
+ result = KeyPress(self.mappings[ascii_char], u_char)
else:
- if ascii_char in self.mappings:
- if self.mappings[ascii_char] == Keys.ControlJ:
- u_char = (
- "\n" # Windows sends \n, turn into \r for unix compatibility.
- )
- result = KeyPress(self.mappings[ascii_char], u_char)
- else:
- result = KeyPress(u_char, u_char)
+ result = KeyPress(u_char, u_char)
# First we handle Shift-Control-Arrow/Home/End (need to do this first)
if (
@@ -496,24 +495,12 @@ def _event_to_key_presses(self, ev: KEY_EVENT_RECORD) -> List[KeyPress]:
):
return [KeyPress(Keys.Escape, ""), result]
- # Return result. If alt was pressed, prefix the result with an
- # 'Escape' key, just like unix VT100 terminals do.
-
- # NOTE: Only replace the left alt with escape. The right alt key often
- # acts as altgr and is used in many non US keyboard layouts for
- # typing some special characters, like a backslash. We don't want
- # all backslashes to be prefixed with escape. (Esc-\ has a
- # meaning in E-macs, for instance.)
- if result:
- meta_pressed = control_key_state & self.LEFT_ALT_PRESSED
-
- if meta_pressed:
- return [KeyPress(Keys.Escape, ""), result]
- else:
- return [result]
-
- else:
+ if not result:
return []
+ if meta_pressed := control_key_state & self.LEFT_ALT_PRESSED:
+ return [KeyPress(Keys.Escape, ""), result]
+ else:
+ return [result]
def _handle_mouse(self, ev: MOUSE_EVENT_RECORD) -> List[KeyPress]:
"""
@@ -527,23 +514,22 @@ def _handle_mouse(self, ev: MOUSE_EVENT_RECORD) -> List[KeyPress]:
# Scroll events.
if event_flags & MOUSE_WHEELED:
- if button_state > 0:
- event_type = MouseEventType.SCROLL_UP
- else:
- event_type = MouseEventType.SCROLL_DOWN
- else:
- # Handle button state for non-scroll events.
- if button_state == FROM_LEFT_1ST_BUTTON_PRESSED:
- button = MouseButton.LEFT
+ event_type = (
+ MouseEventType.SCROLL_UP
+ if button_state > 0
+ else MouseEventType.SCROLL_DOWN
+ )
+
+ elif button_state == FROM_LEFT_1ST_BUTTON_PRESSED:
+ button = MouseButton.LEFT
- elif button_state == RIGHTMOST_BUTTON_PRESSED:
- button = MouseButton.RIGHT
+ elif button_state == RIGHTMOST_BUTTON_PRESSED:
+ button = MouseButton.RIGHT
# Move events.
if event_flags & MOUSE_MOVED:
event_type = MouseEventType.MOUSE_MOVE
- # No key pressed anymore: mouse up.
if event_type is None:
if button_state > 0:
# Some button pressed.
diff --git a/src/prompt_toolkit/key_binding/bindings/auto_suggest.py b/src/prompt_toolkit/key_binding/bindings/auto_suggest.py
index c016c0688f..0688b50fcf 100644
--- a/src/prompt_toolkit/key_binding/bindings/auto_suggest.py
+++ b/src/prompt_toolkit/key_binding/bindings/auto_suggest.py
@@ -43,9 +43,7 @@ def _accept(event: E) -> None:
Accept suggestion.
"""
b = event.current_buffer
- suggestion = b.suggestion
-
- if suggestion:
+ if suggestion := b.suggestion:
b.insert_text(suggestion.text)
@handle("escape", "f", filter=suggestion_available & emacs_mode)
@@ -54,9 +52,7 @@ def _fill(event: E) -> None:
Fill partial suggestion.
"""
b = event.current_buffer
- suggestion = b.suggestion
-
- if suggestion:
+ if suggestion := b.suggestion:
t = re.split(r"(\S+\s+)", suggestion.text)
b.insert_text(next(x for x in t if x))
diff --git a/src/prompt_toolkit/key_binding/bindings/emacs.py b/src/prompt_toolkit/key_binding/bindings/emacs.py
index a4a5e348f8..df76aa6c60 100644
--- a/src/prompt_toolkit/key_binding/bindings/emacs.py
+++ b/src/prompt_toolkit/key_binding/bindings/emacs.py
@@ -496,10 +496,13 @@ def _extend_selection(event: E) -> None:
unshift_move(event)
buff = event.current_buffer
- if buff.selection_state is not None:
- if buff.cursor_position == buff.selection_state.original_cursor_position:
- # selection is now empty, so cancel selection
- buff.exit_selection()
+ if (
+ buff.selection_state is not None
+ and buff.cursor_position
+ == buff.selection_state.original_cursor_position
+ ):
+ # selection is now empty, so cancel selection
+ buff.exit_selection()
@handle(Keys.Any, filter=shift_selection_mode)
def _replace_selection(event: E) -> None:
diff --git a/src/prompt_toolkit/key_binding/bindings/named_commands.py b/src/prompt_toolkit/key_binding/bindings/named_commands.py
index e0796ef0b8..af5bf77364 100644
--- a/src/prompt_toolkit/key_binding/bindings/named_commands.py
+++ b/src/prompt_toolkit/key_binding/bindings/named_commands.py
@@ -126,9 +126,7 @@ def forward_word(event: E) -> None:
digits.
"""
buff = event.current_buffer
- pos = buff.document.find_next_word_ending(count=event.arg)
-
- if pos:
+ if pos := buff.document.find_next_word_ending(count=event.arg):
buff.cursor_position += pos
@@ -139,9 +137,7 @@ def backward_word(event: E) -> None:
of letters and digits.
"""
buff = event.current_buffer
- pos = buff.document.find_previous_word_beginning(count=event.arg)
-
- if pos:
+ if pos := buff.document.find_previous_word_beginning(count=event.arg):
buff.cursor_position += pos
@@ -296,7 +292,7 @@ def uppercase_word(event: E) -> None:
"""
buff = event.current_buffer
- for i in range(event.arg):
+ for _ in range(event.arg):
pos = buff.document.find_next_word_ending()
words = buff.document.text_after_cursor[:pos]
buff.insert_text(words.upper(), overwrite=True)
@@ -309,7 +305,7 @@ def downcase_word(event: E) -> None:
"""
buff = event.current_buffer
- for i in range(event.arg): # XXX: not DRY: see meta_c and meta_u!!
+ for _ in range(event.arg):
pos = buff.document.find_next_word_ending()
words = buff.document.text_after_cursor[:pos]
buff.insert_text(words.lower(), overwrite=True)
@@ -322,7 +318,7 @@ def capitalize_word(event: E) -> None:
"""
buff = event.current_buffer
- for i in range(event.arg):
+ for _ in range(event.arg):
pos = buff.document.find_next_word_ending()
words = buff.document.text_after_cursor[:pos]
buff.insert_text(words.title(), overwrite=True)
@@ -356,11 +352,10 @@ def kill_line(event: E) -> None:
deleted = buff.delete_before_cursor(
count=-buff.document.get_start_of_line_position()
)
+ elif buff.document.current_char == "\n":
+ deleted = buff.delete(1)
else:
- if buff.document.current_char == "\n":
- deleted = buff.delete(1)
- else:
- deleted = buff.delete(count=buff.document.get_end_of_line_position())
+ deleted = buff.delete(count=buff.document.get_end_of_line_position())
event.app.clipboard.set_text(deleted)
@@ -371,9 +366,7 @@ def kill_word(event: E) -> None:
end of the next word. Word boundaries are the same as forward-word.
"""
buff = event.current_buffer
- pos = buff.document.find_next_word_ending(count=event.arg)
-
- if pos:
+ if pos := buff.document.find_next_word_ending(count=event.arg):
deleted = buff.delete(count=pos)
if event.is_repeat:
@@ -490,10 +483,10 @@ def yank_pop(event: E) -> None:
"""
buff = event.current_buffer
doc_before_paste = buff.document_before_paste
- clipboard = event.app.clipboard
-
if doc_before_paste is not None:
buff.document = doc_before_paste
+ clipboard = event.app.clipboard
+
clipboard.rotate()
buff.paste_clipboard_data(clipboard.get_data(), paste_mode=PasteMode.EMACS)
@@ -562,10 +555,7 @@ def call_last_kbd_macro(event: E) -> None:
the body of the called macro back into the KeyProcessor, so these keys will
be added later on to the macro of their handlers have `record_in_macro=True`.
"""
- # Insert the macro.
- macro = event.app.emacs_state.macro
-
- if macro:
+ if macro := event.app.emacs_state.macro:
event.app.key_processor.feed_multiple(macro, first=True)
@@ -576,8 +566,7 @@ def print_last_kbd_macro(event: E) -> None:
"""
# TODO: Make the format suitable for the inputrc file.
def print_macro() -> None:
- macro = event.app.emacs_state.macro
- if macro:
+ if macro := event.app.emacs_state.macro:
for k in macro:
print(k)
@@ -617,7 +606,7 @@ def change(line: str) -> str:
else:
def change(line: str) -> str:
- return "#" + line
+ return f"#{line}"
buff.document = Document(
text="\n".join(map(change, buff.text.splitlines())), cursor_position=0
diff --git a/src/prompt_toolkit/key_binding/bindings/scroll.py b/src/prompt_toolkit/key_binding/bindings/scroll.py
index 4a43ff585a..34b2c3d19a 100644
--- a/src/prompt_toolkit/key_binding/bindings/scroll.py
+++ b/src/prompt_toolkit/key_binding/bindings/scroll.py
@@ -101,16 +101,14 @@ def scroll_one_line_down(event: E) -> None:
w = event.app.layout.current_window
b = event.app.current_buffer
- if w:
- # When the cursor is at the top, move to the next line. (Otherwise, only scroll.)
- if w.render_info:
- info = w.render_info
+ if w and w.render_info:
+ info = w.render_info
- if w.vertical_scroll < info.content_height - info.window_height:
- if info.cursor_position.y <= info.configured_scroll_offsets.top:
- b.cursor_position += b.document.get_cursor_down_position()
+ if w.vertical_scroll < info.content_height - info.window_height:
+ if info.cursor_position.y <= info.configured_scroll_offsets.top:
+ b.cursor_position += b.document.get_cursor_down_position()
- w.vertical_scroll += 1
+ w.vertical_scroll += 1
def scroll_one_line_up(event: E) -> None:
@@ -118,30 +116,27 @@ def scroll_one_line_up(event: E) -> None:
scroll_offset -= 1
"""
w = event.app.layout.current_window
- b = event.app.current_buffer
+ if w and w.render_info and w.vertical_scroll > 0:
+ b = event.app.current_buffer
- if w:
- # When the cursor is at the bottom, move to the previous line. (Otherwise, only scroll.)
- if w.render_info:
- info = w.render_info
+ info = w.render_info
- if w.vertical_scroll > 0:
- first_line_height = info.get_height_for_line(info.first_visible_line())
+ first_line_height = info.get_height_for_line(info.first_visible_line())
- cursor_up = info.cursor_position.y - (
- info.window_height
- - 1
- - first_line_height
- - info.configured_scroll_offsets.bottom
- )
+ cursor_up = info.cursor_position.y - (
+ info.window_height
+ - 1
+ - first_line_height
+ - info.configured_scroll_offsets.bottom
+ )
- # Move cursor up, as many steps as the height of the first line.
- # TODO: not entirely correct yet, in case of line wrapping and many long lines.
- for _ in range(max(0, cursor_up)):
- b.cursor_position += b.document.get_cursor_up_position()
+ # Move cursor up, as many steps as the height of the first line.
+ # TODO: not entirely correct yet, in case of line wrapping and many long lines.
+ for _ in range(max(0, cursor_up)):
+ b.cursor_position += b.document.get_cursor_up_position()
- # Scroll window
- w.vertical_scroll -= 1
+ # Scroll window
+ w.vertical_scroll -= 1
def scroll_page_down(event: E) -> None:
diff --git a/src/prompt_toolkit/key_binding/bindings/vi.py b/src/prompt_toolkit/key_binding/bindings/vi.py
index efbb107de0..73f991aad9 100644
--- a/src/prompt_toolkit/key_binding/bindings/vi.py
+++ b/src/prompt_toolkit/key_binding/bindings/vi.py
@@ -52,7 +52,7 @@
ascii_lowercase = string.ascii_lowercase
-vi_register_names = ascii_lowercase + "0123456789"
+vi_register_names = f"{ascii_lowercase}0123456789"
class TextObjectType(Enum):
@@ -646,7 +646,7 @@ def _delete_line(event: E) -> None:
# Set new text.
if before and after:
- before = before + "\n"
+ before += "\n"
# Set text and cursor position.
buffer.document = Document(
@@ -727,7 +727,7 @@ def _join(event: E) -> None:
"""
Join lines.
"""
- for i in range(event.arg):
+ for _ in range(event.arg):
event.current_buffer.join_next_line()
@handle("g", "J", filter=vi_navigation_mode & ~is_read_only)
@@ -735,7 +735,7 @@ def _join_nospace(event: E) -> None:
"""
Join lines without space.
"""
- for i in range(event.arg):
+ for _ in range(event.arg):
event.current_buffer.join_next_line(separator="")
@handle("J", filter=vi_selection_mode & ~is_read_only)
@@ -781,8 +781,7 @@ def _paste_register(event: E) -> None:
"""
c = event.key_sequence[1].data
if c in vi_register_names:
- data = event.app.vi_state.named_registers.get(c)
- if data:
+ if data := event.app.vi_state.named_registers.get(c):
event.current_buffer.paste_clipboard_data(
data, count=event.arg, paste_mode=PasteMode.VI_AFTER
)
@@ -794,8 +793,7 @@ def _paste_register_before(event: E) -> None:
"""
c = event.key_sequence[1].data
if c in vi_register_names:
- data = event.app.vi_state.named_registers.get(c)
- if data:
+ if data := event.app.vi_state.named_registers.get(c):
event.current_buffer.paste_clipboard_data(
data, count=event.arg, paste_mode=PasteMode.VI_BEFORE
)
@@ -826,7 +824,7 @@ def _substitute(event: E) -> None:
@handle("u", filter=vi_navigation_mode, save_before=(lambda e: False))
def _undo(event: E) -> None:
- for i in range(event.arg):
+ for _ in range(event.arg):
event.current_buffer.undo()
@handle("V", filter=vi_navigation_mode)
@@ -912,16 +910,14 @@ def _delete(event: E) -> None:
Delete character.
"""
buff = event.current_buffer
- count = min(event.arg, len(buff.document.current_line_after_cursor))
- if count:
+ if count := min(event.arg, len(buff.document.current_line_after_cursor)):
text = event.current_buffer.delete(count=count)
event.app.clipboard.set_text(text)
@handle("X", filter=vi_navigation_mode)
def _delete_before_cursor(event: E) -> None:
buff = event.current_buffer
- count = min(event.arg, len(buff.document.current_line_before_cursor))
- if count:
+ if count := min(event.arg, len(buff.document.current_line_before_cursor)):
text = event.current_buffer.delete_before_cursor(count=count)
event.app.clipboard.set_text(text)
@@ -1359,12 +1355,11 @@ def handler(event: E) -> TextObject:
ci_start, ci_end
)
- if start is not None and end is not None:
- offset = 0 if inner else 1
- return TextObject(start + 1 - offset, end + offset)
- else:
+ if start is None or end is None:
# Nothing found.
return TextObject(0)
+ offset = 0 if inner else 1
+ return TextObject(start + 1 - offset, end + offset)
if key is None:
text_object("ai"[inner], ci_start, no_move_handler=True)(handler)
@@ -1416,10 +1411,9 @@ def _next_occurence(event: E) -> TextObject:
cursor to the next occurrence of character. 'x'.
"""
event.app.vi_state.last_character_find = CharacterFind(event.data, False)
- match = event.current_buffer.document.find(
+ if match := event.current_buffer.document.find(
event.data, in_current_line=True, count=event.arg
- )
- if match:
+ ):
return TextObject(match, type=TextObjectType.INCLUSIVE)
else:
return TextObject(0)
@@ -1444,10 +1438,9 @@ def _t(event: E) -> TextObject:
Move right to the next occurrence of c, then one char backward.
"""
event.app.vi_state.last_character_find = CharacterFind(event.data, False)
- match = event.current_buffer.document.find(
+ if match := event.current_buffer.document.find(
event.data, in_current_line=True, count=event.arg
- )
- if match:
+ ):
return TextObject(match - 1, type=TextObjectType.INCLUSIVE)
else:
return TextObject(0)
@@ -1494,10 +1487,7 @@ def _(event: E) -> TextObject:
char, in_current_line=True, count=event.arg
)
type = TextObjectType.INCLUSIVE
- if pos:
- return TextObject(pos, type=type)
- else:
- return TextObject(0)
+ return TextObject(pos, type=type) if pos else TextObject(0)
repeat(True)
repeat(False)
@@ -1722,27 +1712,25 @@ def _goto_corresponding_bracket(event: E) -> TextObject:
"""
buffer = event.current_buffer
- if event._arg:
- # If 'arg' has been given, the meaning of % is to go to the 'x%'
- # row in the file.
- if 0 < event.arg <= 100:
- absolute_index = buffer.document.translate_row_col_to_index(
- int((event.arg * buffer.document.line_count - 1) / 100), 0
- )
- return TextObject(
- absolute_index - buffer.document.cursor_position,
- type=TextObjectType.LINEWISE,
- )
- else:
- return TextObject(0) # Do nothing.
+ if not event._arg:
+ return (
+ TextObject(match, type=TextObjectType.INCLUSIVE)
+ if (match := buffer.document.find_matching_bracket_position())
+ else TextObject(0)
+ )
+ # If 'arg' has been given, the meaning of % is to go to the 'x%'
+ # row in the file.
+ if 0 < event.arg <= 100:
+ absolute_index = buffer.document.translate_row_col_to_index(
+ int((event.arg * buffer.document.line_count - 1) / 100), 0
+ )
+ return TextObject(
+ absolute_index - buffer.document.cursor_position,
+ type=TextObjectType.LINEWISE,
+ )
else:
- # Move to the corresponding opening/closing bracket (()'s, []'s and {}'s).
- match = buffer.document.find_matching_bracket_position()
- if match:
- return TextObject(match, type=TextObjectType.INCLUSIVE)
- else:
- return TextObject(0)
+ return TextObject(0) # Do nothing.
@text_object("|")
def _to_column(event: E) -> TextObject:
@@ -1912,8 +1900,7 @@ def _insert_text_multiple_cursors(event: E) -> None:
p = 0
for p2 in buff.multiple_cursor_positions:
- text.append(original_text[p:p2])
- text.append(event.data)
+ text.extend((original_text[p:p2], event.data))
p = p2
text.append(original_text[p:])
diff --git a/src/prompt_toolkit/key_binding/key_bindings.py b/src/prompt_toolkit/key_binding/key_bindings.py
index 03bc79ef01..6b5cd48990 100644
--- a/src/prompt_toolkit/key_binding/key_bindings.py
+++ b/src/prompt_toolkit/key_binding/key_bindings.py
@@ -344,7 +344,7 @@ def remove(self, *args: Union[Keys, str, KeyHandlerCallable]) -> None:
found = True
else:
- assert len(args) > 0
+ assert args
args = cast(Tuple[Union[Keys, str]], args)
# Remove this sequence of key bindings.
@@ -383,7 +383,7 @@ def get() -> List[Binding]:
any_count = 0
for i, j in zip(b.keys, keys):
- if i != j and i != Keys.Any:
+ if i not in [j, Keys.Any]:
match = False
break
@@ -414,11 +414,7 @@ def get() -> List[Binding]:
result = []
for b in self.bindings:
if len(keys) < len(b.keys):
- match = True
- for i, j in zip(b.keys, keys):
- if i != j and i != Keys.Any:
- match = False
- break
+ match = all(i in [j, Keys.Any] for i, j in zip(b.keys, keys))
if match:
result.append(b)
return result
diff --git a/src/prompt_toolkit/key_binding/key_processor.py b/src/prompt_toolkit/key_binding/key_processor.py
index 6fdd519179..692c24d13c 100644
--- a/src/prompt_toolkit/key_binding/key_processor.py
+++ b/src/prompt_toolkit/key_binding/key_processor.py
@@ -40,11 +40,7 @@ def __init__(self, key: Union[Keys, str], data: Optional[str] = None) -> None:
assert isinstance(key, Keys) or len(key) == 1
if data is None:
- if isinstance(key, Keys):
- data = key.value
- else:
- data = key # 'key' is a one character string.
-
+ data = key.value if isinstance(key, Keys) else key
self.key = key
self.data = data
@@ -52,9 +48,11 @@ def __repr__(self) -> str:
return f"{self.__class__.__name__}(key={self.key!r}, data={self.data!r})"
def __eq__(self, other: object) -> bool:
- if not isinstance(other, KeyPress):
- return False
- return self.key == other.key and self.data == other.data
+ return (
+ self.key == other.key and self.data == other.data
+ if isinstance(other, KeyPress)
+ else False
+ )
"""
@@ -172,35 +170,30 @@ def _process(self) -> Generator[None, KeyPress, None]:
else:
is_prefix_of_longer_match = self._is_prefix_of_longer_match(buffer)
- # When eager matches were found, give priority to them and also
- # ignore all the longer matches.
- eager_matches = [m for m in matches if m.eager()]
-
- if eager_matches:
+ if eager_matches := [m for m in matches if m.eager()]:
matches = eager_matches
is_prefix_of_longer_match = False
# Exact matches found, call handler.
- if not is_prefix_of_longer_match and matches:
- self._call_handler(matches[-1], key_sequence=buffer[:])
- del buffer[:] # Keep reference.
-
- # No match found.
- elif not is_prefix_of_longer_match and not matches:
- retry = True
- found = False
-
- # Loop over the input, try longest match first and shift.
- for i in range(len(buffer), 0, -1):
- matches = self._get_matches(buffer[:i])
- if matches:
- self._call_handler(matches[-1], key_sequence=buffer[:i])
- del buffer[:i]
- found = True
- break
-
- if not found:
- del buffer[:1]
+ if not is_prefix_of_longer_match:
+ if matches:
+ self._call_handler(matches[-1], key_sequence=buffer[:])
+ del buffer[:] # Keep reference.
+
+ else:
+ retry = True
+ found = False
+
+ # Loop over the input, try longest match first and shift.
+ for i in range(len(buffer), 0, -1):
+ if matches := self._get_matches(buffer[:i]):
+ self._call_handler(matches[-1], key_sequence=buffer[:i])
+ del buffer[:i]
+ found = True
+ break
+
+ if not found:
+ del buffer[:1]
def feed(self, key_press: KeyPress, first: bool = False) -> None:
"""
@@ -246,13 +239,12 @@ def not_empty() -> bool:
return bool(self.input_queue)
def get_next() -> KeyPress:
- if app.is_done:
- # Only process CPR responses. Everything else is typeahead.
- cpr = [k for k in self.input_queue if k.key == Keys.CPRResponse][0]
- self.input_queue.remove(cpr)
- return cpr
- else:
+ if not app.is_done:
return self.input_queue.popleft()
+ # Only process CPR responses. Everything else is typeahead.
+ cpr = [k for k in self.input_queue if k.key == Keys.CPRResponse][0]
+ self.input_queue.remove(cpr)
+ return cpr
is_flush = False
@@ -372,10 +364,12 @@ def _leave_vi_temp_navigation_mode(self, event: "KeyPressEvent") -> None:
"""
app = event.app
- if app.editing_mode == EditingMode.VI:
- # Not waiting for a text object and no argument has been given.
- if app.vi_state.operator_func is None and self.arg is None:
- app.vi_state.temporary_navigation_mode = False
+ if (
+ app.editing_mode == EditingMode.VI
+ and app.vi_state.operator_func is None
+ and self.arg is None
+ ):
+ app.vi_state.temporary_navigation_mode = False
def _start_timeout(self) -> None:
"""
@@ -491,7 +485,7 @@ def arg(self) -> int:
result = int(self._arg or 1)
# Don't exceed a million.
- if int(result) >= 1000000:
+ if result >= 1000000:
result = 1
return result
diff --git a/src/prompt_toolkit/layout/containers.py b/src/prompt_toolkit/layout/containers.py
index 03f9e7d248..4eabe37271 100644
--- a/src/prompt_toolkit/layout/containers.py
+++ b/src/prompt_toolkit/layout/containers.py
@@ -347,14 +347,17 @@ def get() -> List[Container]:
# The children with padding.
for child in self.children:
- result.append(child)
- result.append(
- Window(
- height=self.padding,
- char=self.padding_char,
- style=self.padding_style,
+ result.extend(
+ (
+ child,
+ Window(
+ height=self.padding,
+ char=self.padding_char,
+ style=self.padding_style,
+ ),
)
)
+
if result:
result.pop()
@@ -382,7 +385,7 @@ def write_to_screen(
to which the output has to be written.
"""
sizes = self._divide_heights(write_position)
- style = parent_style + " " + to_str(self.style)
+ style = f"{parent_style} {to_str(self.style)}"
z_index = z_index if self.z_index is None else self.z_index
if sizes is None:
@@ -574,12 +577,11 @@ def preferred_height(self, width: int, max_available_height: int) -> Dimension:
if sizes is None:
return Dimension()
- else:
- dimensions = [
- c.preferred_height(s, max_available_height)
- for s, c in zip(sizes, children)
- ]
- return max_layout_dimensions(dimensions)
+ dimensions = [
+ c.preferred_height(s, max_available_height)
+ for s, c in zip(sizes, children)
+ ]
+ return max_layout_dimensions(dimensions)
def reset(self) -> None:
for c in self.children:
@@ -600,14 +602,17 @@ def get() -> List[Container]:
# The children with padding.
for child in self.children:
- result.append(child)
- result.append(
- Window(
- width=self.padding,
- char=self.padding_char,
- style=self.padding_style,
+ result.extend(
+ (
+ child,
+ Window(
+ width=self.padding,
+ char=self.padding_char,
+ style=self.padding_style,
+ ),
)
)
+
if result:
result.pop()
@@ -690,7 +695,7 @@ def write_to_screen(
children = self._all_children
sizes = self._divide_widths(write_position.width)
- style = parent_style + " " + to_str(self.style)
+ style = f"{parent_style} {to_str(self.style)}"
z_index = z_index if self.z_index is None else self.z_index
# If there is not enough space.
@@ -804,7 +809,7 @@ def write_to_screen(
erase_bg: bool,
z_index: Optional[int],
) -> None:
- style = parent_style + " " + to_str(self.style)
+ style = f"{parent_style} {to_str(self.style)}"
z_index = z_index if self.z_index is None else self.z_index
self.content.write_to_screen(
@@ -815,7 +820,7 @@ def write_to_screen(
# z_index of a Float is computed by summing the z_index of the
# container and the `Float`.
new_z_index = (z_index or 0) + fl.z_index
- style = parent_style + " " + to_str(self.style)
+ style = f"{parent_style} {to_str(self.style)}"
# If the float that we have here, is positioned relative to the
# cursor position, but the Window that specifies the cursor
@@ -1094,14 +1099,10 @@ def __init__(
self.transparent = to_filter(transparent)
def get_width(self) -> Optional[int]:
- if callable(self.width):
- return self.width()
- return self.width
+ return self.width() if callable(self.width) else self.width
def get_height(self) -> Optional[int]:
- if callable(self.height):
- return self.height()
- return self.height
+ return self.height() if callable(self.height) else self.height
def __repr__(self) -> str:
return "Float(content=%r)" % self.content
@@ -1233,10 +1234,7 @@ def input_line_to_visible_line(self) -> Dict[int, int]:
"""
result: Dict[int, int] = {}
for k, v in self.visible_line_to_input_line.items():
- if v in result:
- result[v] = min(result[v], k)
- else:
- result[v] = k
+ result[v] = min(result[v], k) if v in result else k
return result
def first_visible_line(self, after_scroll_offset: bool = False) -> int:
@@ -1693,9 +1691,7 @@ def _get_digraph_char(self) -> Optional[str]:
if app.quoted_insert:
return "^"
if app.vi_state.waiting_for_digraph:
- if app.vi_state.digraph_symbol1:
- return app.vi_state.digraph_symbol1
- return "?"
+ return app.vi_state.digraph_symbol1 or "?"
return None
def write_to_screen(
@@ -1987,11 +1983,7 @@ def copy_line(
multiple lines in the output. It will call the prefix (prompt)
function before every line.
"""
- if is_input:
- current_rowcol_to_yx = rowcol_to_yx
- else:
- current_rowcol_to_yx = {} # Throwaway dictionary.
-
+ current_rowcol_to_yx = rowcol_to_yx if is_input else {}
# Draw line prefix.
if is_input and get_line_prefix:
prompt = to_formatted_text(get_line_prefix(lineno, 0))
@@ -2188,11 +2180,7 @@ def _fill_bg(
(Useful for floats and when a `char` has been given.)
"""
char: Optional[str]
- if callable(self.char):
- char = self.char()
- else:
- char = self.char
-
+ char = self.char() if callable(self.char) else self.char
if erase_bg or char:
wp = write_position
char_obj = _CHAR_CACHE[char or " ", ""]
@@ -2207,7 +2195,7 @@ def _apply_style(
) -> None:
# Apply `self.style`.
- style = parent_style + " " + to_str(self.style)
+ style = f"{parent_style} {to_str(self.style)}"
new_screen.fill_area(write_position, style=style, after=False)
@@ -2226,8 +2214,7 @@ def _highlight_digraph(self, new_screen: Screen) -> None:
When we are in Vi digraph mode, put a question mark underneath the
cursor.
"""
- digraph_char = self._get_digraph_char()
- if digraph_char:
+ if digraph_char := self._get_digraph_char():
cpos = new_screen.get_cursor_position(self)
new_screen.data_buffer[cpos.y][cpos.x] = _CHAR_CACHE[
digraph_char, "class:digraph"
@@ -2262,14 +2249,12 @@ def _highlight_cursorlines(
"""
Highlight cursor row/column.
"""
- cursor_line_style = " class:cursor-line "
- cursor_column_style = " class:cursor-column "
-
data_buffer = new_screen.data_buffer
# Highlight cursor line.
if self.cursorline():
row = data_buffer[cpos.y]
+ cursor_line_style = " class:cursor-line "
for x in range(x, x + width):
original_char = row[x]
row[x] = _CHAR_CACHE[
@@ -2278,6 +2263,8 @@ def _highlight_cursorlines(
# Highlight cursor column.
if self.cursorcolumn():
+ cursor_column_style = " class:cursor-column "
+
for y2 in range(y, y + height):
row = data_buffer[y2]
original_char = row[cpos.x]
@@ -2295,7 +2282,7 @@ def _highlight_cursorlines(
column = cc.position
if column < x + width: # Only draw when visible.
- color_column_style = " " + cc.style
+ color_column_style = f" {cc.style}"
for y2 in range(y, y + height):
row = data_buffer[y2]
@@ -2497,9 +2484,7 @@ def do_scroll(
)
# Prevent negative scroll offsets.
- if current_scroll < 0:
- current_scroll = 0
-
+ current_scroll = max(current_scroll, 0)
# Scroll back if we scrolled to much and there's still space to show more of the document.
if (
not self.allow_scroll_beyond_bottom()
diff --git a/src/prompt_toolkit/layout/controls.py b/src/prompt_toolkit/layout/controls.py
index 016d289466..0bdd1ec56c 100644
--- a/src/prompt_toolkit/layout/controls.py
+++ b/src/prompt_toolkit/layout/controls.py
@@ -368,15 +368,14 @@ def preferred_height(
Return the preferred height for this control.
"""
content = self.create_content(width, None)
- if wrap_lines:
- height = 0
- for i in range(content.line_count):
- height += content.get_height_for_line(i, width, get_line_prefix)
- if height >= max_available_height:
- return max_available_height
- return height
- else:
+ if not wrap_lines:
return content.line_count
+ height = 0
+ for i in range(content.line_count):
+ height += content.get_height_for_line(i, width, get_line_prefix)
+ if height >= max_available_height:
+ return max_available_height
+ return height
def create_content(self, width: int, height: Optional[int]) -> UIContent:
# Get fragments
@@ -598,8 +597,7 @@ def search_state(self) -> SearchState:
for searching multiple `BufferControls`, then they share the same
`SearchState`.
"""
- search_buffer_control = self.search_buffer_control
- if search_buffer_control:
+ if search_buffer_control := self.search_buffer_control:
return search_buffer_control.searcher_search_state
else:
return SearchState()
@@ -885,18 +883,16 @@ def mouse_handler(self, mouse_event: MouseEvent) -> "NotImplementedOrNone":
# Don't handle scroll events here.
return NotImplemented
- # Not focused, but focusing on click events.
- else:
- if (
+ elif (
self.focus_on_click()
and mouse_event.event_type == MouseEventType.MOUSE_UP
):
- # Focus happens on mouseup. (If we did this on mousedown, the
- # up event will be received at the point where this widget is
- # focused and be handled anyway.)
- get_app().layout.current_control = self
- else:
- return NotImplemented
+ # Focus happens on mouseup. (If we did this on mousedown, the
+ # up event will be received at the point where this widget is
+ # focused and be handled anyway.)
+ get_app().layout.current_control = self
+ else:
+ return NotImplemented
return None
diff --git a/src/prompt_toolkit/layout/dimension.py b/src/prompt_toolkit/layout/dimension.py
index 04c21637cb..4a7da26e31 100644
--- a/src/prompt_toolkit/layout/dimension.py
+++ b/src/prompt_toolkit/layout/dimension.py
@@ -111,7 +111,7 @@ def __repr__(self) -> str:
if self.weight_specified:
fields.append("weight=%r" % self.weight)
- return "Dimension(%s)" % ", ".join(fields)
+ return f'Dimension({", ".join(fields)})'
def sum_layout_dimensions(dimensions: List[Dimension]) -> Dimension:
@@ -139,10 +139,7 @@ def max_layout_dimensions(dimensions: List[Dimension]) -> Dimension:
if all(d.is_zero() for d in dimensions):
return dimensions[0]
- # Ignore empty dimensions. (They should not reduce the size of others.)
- dimensions = [d for d in dimensions if not d.is_zero()]
-
- if dimensions:
+ if dimensions := [d for d in dimensions if not d.is_zero()]:
# Take the highest minimum dimension.
min_ = max(d.min for d in dimensions)
diff --git a/src/prompt_toolkit/layout/layout.py b/src/prompt_toolkit/layout/layout.py
index 62a3184ee2..c51b52ee97 100644
--- a/src/prompt_toolkit/layout/layout.py
+++ b/src/prompt_toolkit/layout/layout.py
@@ -105,7 +105,6 @@ def focus(self, value: FocusableElement) -> None:
return
raise ValueError(f"Couldn't find Buffer in the current layout: {value!r}.")
- # BufferControl by buffer object.
elif isinstance(value, Buffer):
for control in self.find_all_controls():
if isinstance(control, BufferControl) and control.buffer == value:
@@ -113,7 +112,6 @@ def focus(self, value: FocusableElement) -> None:
return
raise ValueError(f"Couldn't find Buffer in the current layout: {value!r}.")
- # Focus UIControl.
elif isinstance(value, UIControl):
if value not in self.find_all_controls():
raise ValueError(
@@ -124,7 +122,6 @@ def focus(self, value: FocusableElement) -> None:
self.current_control = value
- # Otherwise, expecting any Container object.
else:
value = to_container(value)
@@ -143,10 +140,11 @@ def focus(self, value: FocusableElement) -> None:
# of them have been focused before, take the last focused
# item. (This is very useful when the UI is composed of more
# complex sub components.)
- windows = []
- for c in walk(value, skip_hidden=True):
- if isinstance(c, Window) and c.content.is_focusable():
- windows.append(c)
+ windows = [
+ c
+ for c in walk(value, skip_hidden=True)
+ if isinstance(c, Window) and c.content.is_focusable()
+ ]
# Take the first one that was focused before.
for w in reversed(self._stack):
@@ -176,17 +174,12 @@ def has_focus(self, value: FocusableElement) -> bool:
return self.current_buffer == value
if isinstance(value, UIControl):
return self.current_control == value
- else:
- value = to_container(value)
- if isinstance(value, Window):
- return self.current_window == value
- else:
- # Check whether this "container" is focused. This is true if
- # one of the elements inside is focused.
- for element in walk(value):
- if element == self.current_window:
- return True
- return False
+ value = to_container(value)
+ return (
+ self.current_window == value
+ if isinstance(value, Window)
+ else any(element == self.current_window for element in walk(value))
+ )
@property
def current_control(self) -> UIControl:
@@ -269,11 +262,16 @@ def get_buffer_by_name(self, buffer_name: str) -> Optional[Buffer]:
Look in the layout for a buffer with the given name.
Return `None` when nothing was found.
"""
- for w in self.walk():
- if isinstance(w, Window) and isinstance(w.content, BufferControl):
- if w.content.buffer.name == buffer_name:
- return w.content.buffer
- return None
+ return next(
+ (
+ w.content.buffer
+ for w in self.walk()
+ if isinstance(w, Window)
+ and isinstance(w.content, BufferControl)
+ and w.content.buffer.name == buffer_name
+ ),
+ None,
+ )
@property
def buffer_has_focus(self) -> bool:
diff --git a/src/prompt_toolkit/layout/margins.py b/src/prompt_toolkit/layout/margins.py
index 7c46819c24..c8094db0fc 100644
--- a/src/prompt_toolkit/layout/margins.py
+++ b/src/prompt_toolkit/layout/margins.py
@@ -82,7 +82,7 @@ def __init__(
def get_width(self, get_ui_content: Callable[[], UIContent]) -> int:
line_count = get_ui_content().line_count
- return max(3, len("%s" % line_count) + 1)
+ return max(3, len(f"{line_count}") + 1)
def create_margin(
self, window_render_info: "WindowRenderInfo", width: int, height: int
@@ -142,10 +142,7 @@ def __init__(self, margin: Margin, filter: FilterOrBool) -> None:
self.filter = to_filter(filter)
def get_width(self, get_ui_content: Callable[[], UIContent]) -> int:
- if self.filter():
- return self.margin.get_width(get_ui_content)
- else:
- return 0
+ return self.margin.get_width(get_ui_content) if self.filter() else 0
def create_margin(
self, window_render_info: "WindowRenderInfo", width: int, height: int
diff --git a/src/prompt_toolkit/layout/menus.py b/src/prompt_toolkit/layout/menus.py
index 24d6e46af0..43f6e1d3e5 100644
--- a/src/prompt_toolkit/layout/menus.py
+++ b/src/prompt_toolkit/layout/menus.py
@@ -74,8 +74,7 @@ def has_focus(self) -> bool:
return False
def preferred_width(self, max_available_width: int) -> Optional[int]:
- complete_state = get_app().current_buffer.complete_state
- if complete_state:
+ if complete_state := get_app().current_buffer.complete_state:
menu_width = self._get_menu_width(500, complete_state)
menu_meta_width = self._get_menu_meta_width(500, complete_state)
@@ -91,8 +90,7 @@ def preferred_height(
get_line_prefix: Optional[GetLinePrefixCallable],
) -> Optional[int]:
- complete_state = get_app().current_buffer.complete_state
- if complete_state:
+ if complete_state := get_app().current_buffer.complete_state:
return len(complete_state.completions)
else:
return 0
@@ -219,12 +217,10 @@ def _get_menu_item_fragments(
width.
"""
if is_current_completion:
- style_str = "class:completion-menu.completion.current {} {}".format(
- completion.style,
- completion.selected_style,
- )
+ style_str = f"class:completion-menu.completion.current {completion.style} {completion.selected_style}"
+
else:
- style_str = "class:completion-menu.completion " + completion.style
+ style_str = f"class:completion-menu.completion {completion.style}"
text, tw = _trim_formatted_text(
completion.display, (width - 2 if space_after else width - 1)
@@ -247,25 +243,23 @@ def _trim_formatted_text(
"""
width = fragment_list_width(formatted_text)
- # When the text is too wide, trim it.
- if width > max_width:
- result = [] # Text fragments.
- remaining_width = max_width - 3
+ if width <= max_width:
+ return formatted_text, width
+ result = [] # Text fragments.
+ remaining_width = max_width - 3
- for style_and_ch in explode_text_fragments(formatted_text):
- ch_width = get_cwidth(style_and_ch[1])
+ for style_and_ch in explode_text_fragments(formatted_text):
+ ch_width = get_cwidth(style_and_ch[1])
- if ch_width <= remaining_width:
- result.append(style_and_ch)
- remaining_width -= ch_width
- else:
- break
+ if ch_width <= remaining_width:
+ result.append(style_and_ch)
+ remaining_width -= ch_width
+ else:
+ break
- result.append(("", "..."))
+ result.append(("", "..."))
- return result, max_width - remaining_width
- else:
- return formatted_text, width
+ return result, max_width - remaining_width
class CompletionsMenu(ConditionalContainer):
@@ -705,7 +699,6 @@ def get_line(i: int) -> StyleAndTextTuples:
return UIContent(get_line=get_line, line_count=1 if fragments else 0)
def _get_text_fragments(self) -> StyleAndTextTuples:
- style = "class:completion-menu.multi-column-meta"
state = get_app().current_buffer.complete_state
if (
@@ -713,6 +706,7 @@ def _get_text_fragments(self) -> StyleAndTextTuples:
and state.current_completion
and state.current_completion.display_meta_text
):
+ style = "class:completion-menu.multi-column-meta"
return to_formatted_text(
cast(StyleAndTextTuples, [("", " ")])
+ state.current_completion.display_meta
diff --git a/src/prompt_toolkit/layout/processors.py b/src/prompt_toolkit/layout/processors.py
index 722658a846..b5ee8cb532 100644
--- a/src/prompt_toolkit/layout/processors.py
+++ b/src/prompt_toolkit/layout/processors.py
@@ -285,29 +285,25 @@ def apply_transformation(
_,
) = transformation_input.unpack()
- selected_fragment = " class:selected "
-
- # In case of selection, highlight all matches.
- selection_at_line = document.selection_range_at_line(lineno)
-
- if selection_at_line:
+ if selection_at_line := document.selection_range_at_line(lineno):
from_, to = selection_at_line
from_ = source_to_display(from_)
to = source_to_display(to)
fragments = explode_text_fragments(fragments)
+ selected_fragment = " class:selected "
+
if from_ == 0 and to == 0 and len(fragments) == 0:
# When this is an empty line, insert a space in order to
# visualise the selection.
return Transformation([(selected_fragment, " ")])
- else:
- for i in range(from_, to):
- if i < len(fragments):
- old_fragment, old_text, *_ = fragments[i]
- fragments[i] = (old_fragment + selected_fragment, old_text)
- elif i == len(fragments):
- fragments.append((selected_fragment, " "))
+ for i in range(from_, to):
+ if i < len(fragments):
+ old_fragment, old_text, *_ = fragments[i]
+ fragments[i] = (old_fragment + selected_fragment, old_text)
+ elif i == len(fragments):
+ fragments.append((selected_fragment, " "))
return Transformation(fragments)
@@ -417,12 +413,9 @@ def apply_transformation(
# Get the highlight positions.
key = (get_app().render_counter, document.text, document.cursor_position)
- positions = self._positions_cache.get(
+ if positions := self._positions_cache.get(
key, lambda: self._get_positions_to_highlight(document)
- )
-
- # Apply if positions were found at this line.
- if positions:
+ ):
for row, col in positions:
if row == lineno:
col = source_to_display(col)
@@ -484,9 +477,7 @@ def apply_transformation(
style += fragment_suffix
fragments[column] = (style, text)
- return Transformation(fragments)
- else:
- return Transformation(fragments)
+ return Transformation(fragments)
class BeforeInput(Processor):
@@ -544,14 +535,13 @@ def _get_text_fragments(self) -> StyleAndTextTuples:
app = get_app()
if app.key_processor.arg is None:
return []
- else:
- arg = app.key_processor.arg
+ arg = app.key_processor.arg
- return [
- ("class:prompt.arg", "(arg: "),
- ("class:prompt.arg.text", str(arg)),
- ("class:prompt.arg", ") "),
- ]
+ return [
+ ("class:prompt.arg", "(arg: "),
+ ("class:prompt.arg.text", str(arg)),
+ ("class:prompt.arg", ") "),
+ ]
def __repr__(self) -> str:
return "ShowArg()"
@@ -571,13 +561,11 @@ def __init__(self, text: AnyFormattedText, style: str = "") -> None:
self.style = style
def apply_transformation(self, ti: TransformationInput) -> Transformation:
- # Insert fragments after the last line.
- if ti.lineno == ti.document.line_count - 1:
- # Get fragments.
- fragments_after = to_formatted_text(self.text, self.style)
- return Transformation(fragments=ti.fragments + fragments_after)
- else:
+ if ti.lineno != ti.document.line_count - 1:
return Transformation(fragments=ti.fragments)
+ # Get fragments.
+ fragments_after = to_formatted_text(self.text, self.style)
+ return Transformation(fragments=ti.fragments + fragments_after)
def __repr__(self) -> str:
return f"{self.__class__.__name__}({self.text!r}, style={self.style!r})"
@@ -593,18 +581,17 @@ def __init__(self, style: str = "class:auto-suggestion") -> None:
self.style = style
def apply_transformation(self, ti: TransformationInput) -> Transformation:
- # Insert fragments after the last line.
- if ti.lineno == ti.document.line_count - 1:
- buffer = ti.buffer_control.buffer
+ if ti.lineno != ti.document.line_count - 1:
+ return Transformation(fragments=ti.fragments)
+ buffer = ti.buffer_control.buffer
- if buffer.suggestion and ti.document.is_cursor_at_the_end:
- suggestion = buffer.suggestion.text
- else:
- suggestion = ""
+ suggestion = (
+ buffer.suggestion.text
+ if buffer.suggestion and ti.document.is_cursor_at_the_end
+ else ""
+ )
- return Transformation(fragments=ti.fragments + [(self.style, suggestion)])
- else:
- return Transformation(fragments=ti.fragments)
+ return Transformation(fragments=ti.fragments + [(self.style, suggestion)])
class ShowLeadingWhiteSpaceProcessor(Processor):
@@ -816,16 +803,12 @@ def filter_processor(item: Processor) -> Optional[Processor]:
[p for p in accepted_processors if p is not None]
)
- # For a `ConditionalProcessor`, check the body.
elif isinstance(item, ConditionalProcessor):
- p = filter_processor(item.processor)
- if p:
+ if p := filter_processor(item.processor):
return ConditionalProcessor(p, item.filter)
- # Otherwise, check the processor itself.
- else:
- if not isinstance(item, excluded_processors):
- return item
+ elif not isinstance(item, excluded_processors):
+ return item
return None
@@ -966,7 +949,7 @@ def merge_processors(processors: List[Processor]) -> Processor:
"""
Merge multiple `Processor` objects into one.
"""
- if len(processors) == 0:
+ if not processors:
return DummyProcessor()
if len(processors) == 1:
diff --git a/src/prompt_toolkit/layout/screen.py b/src/prompt_toolkit/layout/screen.py
index 8874fba6f8..7f300fea46 100644
--- a/src/prompt_toolkit/layout/screen.py
+++ b/src/prompt_toolkit/layout/screen.py
@@ -106,11 +106,7 @@ class Char:
def __init__(self, char: str = " ", style: str = "") -> None:
# If this character has to be displayed otherwise, take that one.
if char in self.display_mappings:
- if char == "\xa0":
- style += " class:nbsp " # Will be underlined.
- else:
- style += " class:control-character "
-
+ style += " class:nbsp " if char == "\xa0" else " class:control-character "
char = self.display_mappings[char]
self.char = char
@@ -268,7 +264,7 @@ def append_style_to_content(self, style_str: str) -> None:
b = self.data_buffer
char_cache = _CHAR_CACHE
- append_style = " " + style_str
+ append_style = f" {style_str}"
for y, row in b.items():
for x, char in row.items():
@@ -290,11 +286,11 @@ def fill_area(
data_buffer = self.data_buffer
if after:
- append_style = " " + style
+ append_style = f" {style}"
prepend_style = ""
else:
append_style = ""
- prepend_style = style + " "
+ prepend_style = f"{style} "
for y in range(
write_position.ypos, write_position.ypos + write_position.height
diff --git a/src/prompt_toolkit/layout/scrollable_pane.py b/src/prompt_toolkit/layout/scrollable_pane.py
index a5500d7f7c..a232e6d41f 100644
--- a/src/prompt_toolkit/layout/scrollable_pane.py
+++ b/src/prompt_toolkit/layout/scrollable_pane.py
@@ -375,16 +375,14 @@ def _make_window_visible(
min_scroll = 0
max_scroll = virtual_height - visible_height
- if self.keep_cursor_visible():
- # Reduce min/max scroll according to the cursor in the focused window.
- if cursor_position is not None:
- offsets = self.scroll_offsets
- cpos_min_scroll = (
- cursor_position.y - visible_height + 1 + offsets.bottom
- )
- cpos_max_scroll = cursor_position.y - offsets.top
- min_scroll = max(min_scroll, cpos_min_scroll)
- max_scroll = max(0, min(max_scroll, cpos_max_scroll))
+ if self.keep_cursor_visible() and cursor_position is not None:
+ offsets = self.scroll_offsets
+ cpos_min_scroll = (
+ cursor_position.y - visible_height + 1 + offsets.bottom
+ )
+ cpos_max_scroll = cursor_position.y - offsets.top
+ min_scroll = max(min_scroll, cpos_min_scroll)
+ max_scroll = max(0, min(max_scroll, cpos_max_scroll))
if self.keep_focused_window_visible():
# Reduce min/max scroll according to focused window position.
diff --git a/src/prompt_toolkit/layout/utils.py b/src/prompt_toolkit/layout/utils.py
index 2e0f34388b..cfa24710d4 100644
--- a/src/prompt_toolkit/layout/utils.py
+++ b/src/prompt_toolkit/layout/utils.py
@@ -74,7 +74,5 @@ def explode_text_fragments(fragments: Iterable[_T]) -> _ExplodedList[_T]:
result: List[_T] = []
for style, string, *rest in fragments: # type: ignore
- for c in string: # type: ignore
- result.append((style, c, *rest)) # type: ignore
-
+ result.extend((style, c, *rest) for c in string)
return _ExplodedList(result)
diff --git a/src/prompt_toolkit/lexers/pygments.py b/src/prompt_toolkit/lexers/pygments.py
index d50f8afde4..799e45d119 100644
--- a/src/prompt_toolkit/lexers/pygments.py
+++ b/src/prompt_toolkit/lexers/pygments.py
@@ -97,17 +97,13 @@ def get_sync_start_position(
# Scan upwards, until we find a point where we can start the syntax
# synchronisation.
for i in range(lineno, max(-1, lineno - self.MAX_BACKWARDS), -1):
- match = pattern.match(lines[i])
- if match:
+ if match := pattern.match(lines[i]):
return i, match.start()
# No synchronisation point found. If we aren't that far from the
# beginning, start at the very beginning, otherwise, just try to start
# at the current line.
- if lineno < self.FROM_START_IF_NO_SYNC_POS_FOUND:
- return 0, 0
- else:
- return lineno, 0
+ return (0, 0) if lineno < self.FROM_START_IF_NO_SYNC_POS_FOUND else (lineno, 0)
@classmethod
def from_pygments_lexer_cls(cls, lexer_cls: "PygmentsLexerCls") -> "RegexSync":
@@ -138,7 +134,7 @@ class _TokenCache(Dict[Tuple[str, ...], str]):
"""
def __missing__(self, key: Tuple[str, ...]) -> str:
- result = "class:" + pygments_token_to_classname(key)
+ result = f"class:{pygments_token_to_classname(key)}"
self[key] = result
return result
@@ -237,17 +233,18 @@ def lex_document(self, document: Document) -> Callable[[int], StyleAndTextTuples
def get_syntax_sync() -> SyntaxSync:
"The Syntax synchronisation object that we currently use."
- if self.sync_from_start():
- return SyncFromStart()
- else:
- return self.syntax_sync
+ return SyncFromStart() if self.sync_from_start() else self.syntax_sync
def find_closest_generator(i: int) -> Optional[LineGenerator]:
"Return a generator close to line 'i', or None if none was found."
- for generator, lineno in line_generators.items():
- if lineno < i and i - lineno < self.REUSE_GENERATOR_MAX_DISTANCE:
- return generator
- return None
+ return next(
+ (
+ generator
+ for generator, lineno in line_generators.items()
+ if lineno < i and i - lineno < self.REUSE_GENERATOR_MAX_DISTANCE
+ ),
+ None,
+ )
def create_line_generator(start_lineno: int, column: int = 0) -> LineGenerator:
"""
diff --git a/src/prompt_toolkit/output/conemu.py b/src/prompt_toolkit/output/conemu.py
index fc46cc4afd..e6ddfd4b43 100644
--- a/src/prompt_toolkit/output/conemu.py
+++ b/src/prompt_toolkit/output/conemu.py
@@ -45,7 +45,7 @@ def responds_to_cpr(self) -> bool:
return False # We don't need this on Windows.
def __getattr__(self, name: str) -> Any:
- if name in (
+ if name in {
"get_size",
"get_rows_below_cursor_position",
"enable_mouse_support",
@@ -54,7 +54,7 @@ def __getattr__(self, name: str) -> Any:
"get_win32_screen_buffer_info",
"enable_bracketed_paste",
"disable_bracketed_paste",
- ):
+ }:
return getattr(self.win32_output, name)
else:
return getattr(self.vt100_output, name)
diff --git a/src/prompt_toolkit/output/flush_stdout.py b/src/prompt_toolkit/output/flush_stdout.py
index 805a81e010..fd2a838f58 100644
--- a/src/prompt_toolkit/output/flush_stdout.py
+++ b/src/prompt_toolkit/output/flush_stdout.py
@@ -40,15 +40,7 @@ def flush_stdout(stdout: TextIO, data: str) -> None:
# resize signal. (Just ignore. The resize handler will render
# again anyway.)
pass
- elif e.args and e.args[0] == 0:
- # This can happen when there is a lot of output and the user
- # sends a KeyboardInterrupt by pressing Control-C. E.g. in
- # a Python REPL when we execute "while True: print('test')".
- # (The `ptpython` REPL uses this `Output` class instead of
- # `stdout` directly -- in order to be network transparent.)
- # So, just ignore.
- pass
- else:
+ elif not e.args or e.args[0] != 0:
raise
diff --git a/src/prompt_toolkit/output/vt100.py b/src/prompt_toolkit/output/vt100.py
index 3a03de6fa5..9ca5e7b2ee 100644
--- a/src/prompt_toolkit/output/vt100.py
+++ b/src/prompt_toolkit/output/vt100.py
@@ -184,11 +184,7 @@ def _get(
match = _get_closest_ansi_color(r, g, b, exclude=exclude)
# Turn color name into code.
- if self.bg:
- code = BG_ANSI_COLORS[match]
- else:
- code = FG_ANSI_COLORS[match]
-
+ code = BG_ANSI_COLORS[match] if self.bg else FG_ANSI_COLORS[match]
return code, match
@@ -199,25 +195,25 @@ class _256ColorCache(Dict[Tuple[int, int, int], int]):
def __init__(self) -> None:
# Build color table.
- colors: List[Tuple[int, int, int]] = []
-
- # colors 0..15: 16 basic colors
- colors.append((0x00, 0x00, 0x00)) # 0
- colors.append((0xCD, 0x00, 0x00)) # 1
- colors.append((0x00, 0xCD, 0x00)) # 2
- colors.append((0xCD, 0xCD, 0x00)) # 3
- colors.append((0x00, 0x00, 0xEE)) # 4
- colors.append((0xCD, 0x00, 0xCD)) # 5
- colors.append((0x00, 0xCD, 0xCD)) # 6
- colors.append((0xE5, 0xE5, 0xE5)) # 7
- colors.append((0x7F, 0x7F, 0x7F)) # 8
- colors.append((0xFF, 0x00, 0x00)) # 9
- colors.append((0x00, 0xFF, 0x00)) # 10
- colors.append((0xFF, 0xFF, 0x00)) # 11
- colors.append((0x5C, 0x5C, 0xFF)) # 12
- colors.append((0xFF, 0x00, 0xFF)) # 13
- colors.append((0x00, 0xFF, 0xFF)) # 14
- colors.append((0xFF, 0xFF, 0xFF)) # 15
+ colors: List[Tuple[int, int, int]] = [
+ (0x00, 0x00, 0x00),
+ (0xCD, 0x00, 0x00),
+ (0x00, 0xCD, 0x00),
+ (0xCD, 0xCD, 0x00),
+ (0x00, 0x00, 0xEE),
+ (0xCD, 0x00, 0xCD),
+ (0x00, 0xCD, 0xCD),
+ (0xE5, 0xE5, 0xE5),
+ (0x7F, 0x7F, 0x7F),
+ (0xFF, 0x00, 0x00),
+ (0x00, 0xFF, 0x00),
+ (0xFF, 0xFF, 0x00),
+ (0x5C, 0x5C, 0xFF),
+ (0xFF, 0x00, 0xFF),
+ (0x00, 0xFF, 0xFF),
+ (0xFF, 0xFF, 0xFF),
+ ]
+
# colors 16..232: the 6x6x6 color cube
valuerange = (0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF)
@@ -306,11 +302,7 @@ def __missing__(self, attrs: Attrs) -> str:
if strike:
parts.append("9")
- if parts:
- result = "\x1b[0;" + ";".join(parts) + "m"
- else:
- result = "\x1b[0m"
-
+ result = "\x1b[0;" + ";".join(parts) + "m" if parts else "\x1b[0m"
self[attrs] = result
return result
@@ -343,11 +335,9 @@ def get(color: str, bg: bool) -> List[int]:
if not color or self.color_depth == ColorDepth.DEPTH_1_BIT:
return []
- # 16 ANSI colors. (Given by name.)
elif color in table:
return [table[color]]
- # RGB colors. (Defined as 'ffffff'.)
else:
try:
rgb = self._color_name_to_rgb(color)
@@ -357,23 +347,16 @@ def get(color: str, bg: bool) -> List[int]:
# When only 16 colors are supported, use that.
if self.color_depth == ColorDepth.DEPTH_4_BIT:
if bg: # Background.
- if fg_color != bg_color:
- exclude = [fg_ansi]
- else:
- exclude = []
+ exclude = [fg_ansi] if fg_color != bg_color else []
code, name = _16_bg_colors.get_code(rgb, exclude=exclude)
- return [code]
else: # Foreground.
code, name = _16_fg_colors.get_code(rgb)
fg_ansi = name
- return [code]
-
- # True colors. (Only when this feature is enabled.)
+ return [code]
elif self.color_depth == ColorDepth.DEPTH_24_BIT:
r, g, b = rgb
return [(48 if bg else 38), 2, r, g, b]
- # 256 RGB colors.
else:
return [(48 if bg else 38), 5, _256_colors[rgb]]
diff --git a/src/prompt_toolkit/output/win32.py b/src/prompt_toolkit/output/win32.py
index 1724eae5da..3f398bef77 100644
--- a/src/prompt_toolkit/output/win32.py
+++ b/src/prompt_toolkit/output/win32.py
@@ -205,14 +205,9 @@ def get_win32_screen_buffer_info(self) -> CONSOLE_SCREEN_BUFFER_INFO:
self.flush()
sbinfo = CONSOLE_SCREEN_BUFFER_INFO()
- success = windll.kernel32.GetConsoleScreenBufferInfo(
+ if success := windll.kernel32.GetConsoleScreenBufferInfo(
self.hconsole, byref(sbinfo)
- )
-
- # success = self._winapi(windll.kernel32.GetConsoleScreenBufferInfo,
- # self.hconsole, byref(sbinfo))
-
- if success:
+ ):
return sbinfo
else:
raise NoConsoleScreenBufferError
@@ -301,7 +296,7 @@ def set_attributes(self, attrs: Attrs, color_depth: ColorDepth) -> None:
if color_depth != ColorDepth.DEPTH_1_BIT:
# Override the last four bits: foreground color.
if fgcolor:
- win_attrs = win_attrs & ~0xF
+ win_attrs &= ~0xF
win_attrs |= self.color_lookup_table.lookup_fg_color(fgcolor)
# Override the next four bits: background color.
@@ -649,7 +644,7 @@ def _color_indexes(self, color: str) -> Tuple[int, int]:
indexes = self.best_match.get(color, None)
if indexes is None:
try:
- rgb = int(str(color), 16)
+ rgb = int(color, 16)
except ValueError:
rgb = 0
diff --git a/src/prompt_toolkit/output/windows10.py b/src/prompt_toolkit/output/windows10.py
index d5d55f18ca..b7fc01812e 100644
--- a/src/prompt_toolkit/output/windows10.py
+++ b/src/prompt_toolkit/output/windows10.py
@@ -63,7 +63,7 @@ def responds_to_cpr(self) -> bool:
return False # We don't need this on Windows.
def __getattr__(self, name: str) -> Any:
- if name in (
+ if name in {
"get_size",
"get_rows_below_cursor_position",
"enable_mouse_support",
@@ -73,7 +73,7 @@ def __getattr__(self, name: str) -> Any:
"enable_bracketed_paste",
"disable_bracketed_paste",
"get_default_color_depth",
- ):
+ }:
return getattr(self.win32_output, name)
else:
return getattr(self.vt100_output, name)
diff --git a/src/prompt_toolkit/patch_stdout.py b/src/prompt_toolkit/patch_stdout.py
index 0abbcdb847..aca063b777 100644
--- a/src/prompt_toolkit/patch_stdout.py
+++ b/src/prompt_toolkit/patch_stdout.py
@@ -157,9 +157,7 @@ def _write_thread(self) -> None:
if not item:
continue
- text = []
- text.append(item)
-
+ text = [item]
# Read the rest of the queue if more data was queued up.
while True:
try:
diff --git a/src/prompt_toolkit/renderer.py b/src/prompt_toolkit/renderer.py
index 463555c9dd..58c0fd976c 100644
--- a/src/prompt_toolkit/renderer.py
+++ b/src/prompt_toolkit/renderer.py
@@ -110,7 +110,7 @@ def move_cursor(new: Point) -> Point:
if current_x >= width - 1:
write("\r")
_output_cursor_forward(new.x)
- elif new.x < current_x or current_x >= width - 1:
+ elif new.x < current_x:
_output_cursor_backward(current_x - new.x)
elif new.x > current_x:
_output_cursor_forward(new.x - current_x)
@@ -360,10 +360,11 @@ def __init__(
# Future set when we are waiting for a CPR flag.
self._waiting_for_cpr_futures: Deque[Future[None]] = deque()
- self.cpr_support = CPR_Support.UNKNOWN
-
- if not output.responds_to_cpr:
- self.cpr_support = CPR_Support.NOT_SUPPORTED
+ self.cpr_support = (
+ CPR_Support.UNKNOWN
+ if output.responds_to_cpr
+ else CPR_Support.NOT_SUPPORTED
+ )
# Cache for the style.
self._attrs_for_style: Optional[_StyleStringToAttrsCache] = None
diff --git a/src/prompt_toolkit/search.py b/src/prompt_toolkit/search.py
index 413cc6ad9c..f027264b5d 100644
--- a/src/prompt_toolkit/search.py
+++ b/src/prompt_toolkit/search.py
@@ -103,10 +103,7 @@ def start_search(
return
buffer_control = layout.current_control
- # Only if this control is searchable.
- search_buffer_control = buffer_control.search_buffer_control
-
- if search_buffer_control:
+ if search_buffer_control := buffer_control.search_buffer_control:
buffer_control.search_state.direction = direction
# Make sure to focus the search BufferControl
diff --git a/src/prompt_toolkit/shortcuts/dialogs.py b/src/prompt_toolkit/shortcuts/dialogs.py
index eacb05a00c..c0c58d4d2d 100644
--- a/src/prompt_toolkit/shortcuts/dialogs.py
+++ b/src/prompt_toolkit/shortcuts/dialogs.py
@@ -284,7 +284,7 @@ def progress_dialog(
app = _create_app(dialog, style)
def set_percentage(value: int) -> None:
- progressbar.percentage = int(value)
+ progressbar.percentage = value
app.invalidate()
def log_text(text: str) -> None:
diff --git a/src/prompt_toolkit/shortcuts/progress_bar/base.py b/src/prompt_toolkit/shortcuts/progress_bar/base.py
index c22507e25c..4f76b137bd 100644
--- a/src/prompt_toolkit/shortcuts/progress_bar/base.py
+++ b/src/prompt_toolkit/shortcuts/progress_bar/base.py
@@ -336,20 +336,19 @@ def __init__(
self.total = total
def __iter__(self) -> Iterator[_CounterItem]:
- if self.data is not None:
- try:
- for item in self.data:
- yield item
- self.item_completed()
-
- # Only done if we iterate to the very end.
- self.done = True
- finally:
- # Ensure counter has stopped even if we did not iterate to the
- # end (e.g. break or exceptions).
- self.stopped = True
- else:
+ if self.data is None:
raise NotImplementedError("No data defined to iterate over.")
+ try:
+ for item in self.data:
+ yield item
+ self.item_completed()
+
+ # Only done if we iterate to the very end.
+ self.done = True
+ finally:
+ # Ensure counter has stopped even if we did not iterate to the
+ # end (e.g. break or exceptions).
+ self.stopped = True
def item_completed(self) -> None:
"""
diff --git a/src/prompt_toolkit/shortcuts/progress_bar/formatters.py b/src/prompt_toolkit/shortcuts/progress_bar/formatters.py
index 1383d7a6b5..5af006450b 100644
--- a/src/prompt_toolkit/shortcuts/progress_bar/formatters.py
+++ b/src/prompt_toolkit/shortcuts/progress_bar/formatters.py
@@ -116,8 +116,9 @@ def get_width(self, progress_bar: "ProgressBar") -> AnyDimension:
if self.width:
return self.width
- all_labels = [self._add_suffix(c.label) for c in progress_bar.counters]
- if all_labels:
+ if all_labels := [
+ self._add_suffix(c.label) for c in progress_bar.counters
+ ]:
max_widths = max(fragment_list_width(l) for l in all_labels)
return D(preferred=max_widths, max=max_widths)
else:
@@ -181,12 +182,7 @@ def format(
sym_a, sym_b, sym_c = self.sym_a, self.sym_b, self.sym_c
# Compute pb_a based on done, total, or stopped states.
- if progress.done:
- # 100% completed irrelevant of how much was actually marked as completed.
- percent = 1.0
- else:
- # Show percentage completed.
- percent = progress.percentage / 100
+ percent = 1.0 if progress.done else progress.percentage / 100
else:
# Total is unknown and bar is still running.
sym_a, sym_b, sym_c = self.sym_c, self.unknown, self.sym_c
@@ -265,10 +261,9 @@ def format(
)
def get_width(self, progress_bar: "ProgressBar") -> AnyDimension:
- all_values = [
+ if all_values := [
len(_format_timedelta(c.time_elapsed)) for c in progress_bar.counters
- ]
- if all_values:
+ ]:
return max(all_values)
return 0
@@ -326,11 +321,10 @@ def format(
return HTML(self.template.format(iterations_per_second=value))
def get_width(self, progress_bar: "ProgressBar") -> AnyDimension:
- all_values = [
+ if all_values := [
len(f"{c.items_completed / c.time_elapsed.total_seconds():.2f}")
for c in progress_bar.counters
- ]
- if all_values:
+ ]:
return max(all_values)
return 0
@@ -408,8 +402,9 @@ def format(
for i, (style, text, *_) in enumerate(result):
result2.append(
- (style + " " + self.colors[(i + shift) % len(self.colors)], text)
+ (f"{style} {self.colors[(i + shift) % len(self.colors)]}", text)
)
+
return result2
def get_width(self, progress_bar: "ProgressBar") -> AnyDimension:
diff --git a/src/prompt_toolkit/shortcuts/prompt.py b/src/prompt_toolkit/shortcuts/prompt.py
index 4dc1b18d1c..6f6be3bddc 100644
--- a/src/prompt_toolkit/shortcuts/prompt.py
+++ b/src/prompt_toolkit/shortcuts/prompt.py
@@ -165,10 +165,7 @@ def _split_multiline_prompt(
"""
def has_before_fragments() -> bool:
- for fragment, char, *_ in get_prompt_text():
- if "\n" in char:
- return True
- return False
+ return any("\n" in char for fragment, char, *_ in get_prompt_text())
def before() -> StyleAndTextTuples:
result: StyleAndTextTuples = []
@@ -1315,13 +1312,12 @@ def _get_line_prefix(
Return whatever needs to be inserted before every line.
(the prompt, or a line continuation.)
"""
- # First line: display the "arg" or the prompt.
if line_number == 0 and wrap_count == 0:
- if not is_true(self.multiline) and get_app().key_processor.arg is not None:
- return self._inline_arg()
- else:
+ if is_true(self.multiline) or get_app().key_processor.arg is None:
return get_prompt_text_2()
+ else:
+ return self._inline_arg()
# For the next lines, display the appropriate continuation.
prompt_width = get_cwidth(fragment_list_to_text(get_prompt_text_2()))
return self._get_continuation(prompt_width, line_number, wrap_count)
@@ -1343,14 +1339,13 @@ def _inline_arg(self) -> StyleAndTextTuples:
app = get_app()
if app.key_processor.arg is None:
return []
- else:
- arg = app.key_processor.arg
+ arg = app.key_processor.arg
- return [
- ("class:prompt.arg", "(arg: "),
- ("class:prompt.arg.text", str(arg)),
- ("class:prompt.arg", ") "),
- ]
+ return [
+ ("class:prompt.arg", "(arg: "),
+ ("class:prompt.arg.text", str(arg)),
+ ("class:prompt.arg", ") "),
+ ]
# Expose the Input and Output objects as attributes, mainly for
# backward-compatibility.
diff --git a/src/prompt_toolkit/shortcuts/utils.py b/src/prompt_toolkit/shortcuts/utils.py
index a628f4b6ae..82f7821a20 100644
--- a/src/prompt_toolkit/shortcuts/utils.py
+++ b/src/prompt_toolkit/shortcuts/utils.py
@@ -178,11 +178,7 @@ def print_container(
print_container(
Frame(TextArea(text='Hello world!')))
"""
- if file:
- output = create_output(stdout=file)
- else:
- output = get_app_session().output
-
+ output = create_output(stdout=file) if file else get_app_session().output
app: Application[None] = Application(
layout=Layout(container=container),
output=output,
diff --git a/src/prompt_toolkit/styles/defaults.py b/src/prompt_toolkit/styles/defaults.py
index 4ac554562c..2872da2771 100644
--- a/src/prompt_toolkit/styles/defaults.py
+++ b/src/prompt_toolkit/styles/defaults.py
@@ -1,6 +1,7 @@
"""
The default styling.
"""
+
from prompt_toolkit.cache import memoized
from .base import ANSI_COLOR_NAMES, BaseStyle
@@ -126,11 +127,12 @@
# Style that will turn for instance the class 'red' into 'red'.
-COLORS_STYLE = [(name, "fg:" + name) for name in ANSI_COLOR_NAMES] + [
- (name.lower(), "fg:" + name) for name in NAMED_COLORS
+COLORS_STYLE = [(name, f"fg:{name}") for name in ANSI_COLOR_NAMES] + [
+ (name.lower(), f"fg:{name}") for name in NAMED_COLORS
]
+
WIDGETS_STYLE = [
# Dialog windows.
("dialog", "bg:#4444ff"),
diff --git a/src/prompt_toolkit/styles/pygments.py b/src/prompt_toolkit/styles/pygments.py
index 382e5e315b..500abb2d4c 100644
--- a/src/prompt_toolkit/styles/pygments.py
+++ b/src/prompt_toolkit/styles/pygments.py
@@ -48,10 +48,11 @@ def style_from_pygments_dict(pygments_dict: Dict["Token", str]) -> Style:
Create a :class:`.Style` instance from a Pygments style dictionary.
(One that maps Token objects to style strings.)
"""
- pygments_style = []
+ pygments_style = [
+ (pygments_token_to_classname(token), style)
+ for token, style in pygments_dict.items()
+ ]
- for token, style in pygments_dict.items():
- pygments_style.append((pygments_token_to_classname(token), style))
return Style(pygments_style)
diff --git a/src/prompt_toolkit/styles/style.py b/src/prompt_toolkit/styles/style.py
index 6e4bd1f43c..16c6969236 100644
--- a/src/prompt_toolkit/styles/style.py
+++ b/src/prompt_toolkit/styles/style.py
@@ -49,26 +49,24 @@ def parse_color(text: str) -> str:
pass
# Hex codes.
- if text[0:1] == "#":
+ if text.startswith("#"):
col = text[1:]
# Keep this for backwards-compatibility (Pygments does it).
# I don't like the '#' prefix for named colors.
- if col in ANSI_COLOR_NAMES:
+ if (
+ col in ANSI_COLOR_NAMES
+ or col not in ANSI_COLOR_NAMES_ALIASES
+ and len(col) == 6
+ ):
return col
elif col in ANSI_COLOR_NAMES_ALIASES:
return ANSI_COLOR_NAMES_ALIASES[col]
- # 6 digit hex color.
- elif len(col) == 6:
- return col
-
- # 3 digit hex color.
elif len(col) == 3:
return col[0] * 2 + col[1] * 2 + col[2] * 2
- # Default.
- elif text in ("", "default"):
+ elif text in {"", "default"}:
return text
raise ValueError("Wrong color format %r" % text)
@@ -95,13 +93,9 @@ def _expand_classname(classname: str) -> List[str]:
E.g. 'a.b.c' becomes ['a', 'a.b', 'a.b.c']
"""
- result = []
parts = classname.split(".")
- for i in range(1, len(parts) + 1):
- result.append(".".join(parts[:i]).lower())
-
- return result
+ return [".".join(parts[:i]).lower() for i in range(1, len(parts) + 1)]
def _parse_style_str(style_str: str) -> Attrs:
@@ -110,16 +104,12 @@ def _parse_style_str(style_str: str) -> Attrs:
and return a `Attrs` instance.
"""
# Start from default Attrs.
- if "noinherit" in style_str:
- attrs = DEFAULT_ATTRS
- else:
- attrs = _EMPTY_ATTRS
-
+ attrs = DEFAULT_ATTRS if "noinherit" in style_str else _EMPTY_ATTRS
# Now update with the given attributes.
for part in style_str.split():
if part == "noinherit":
- pass
- elif part == "bold":
+ continue
+ if part == "bold":
attrs = attrs._replace(bold=True)
elif part == "nobold":
attrs = attrs._replace(bold=False)
@@ -136,7 +126,6 @@ def _parse_style_str(style_str: str) -> Attrs:
elif part == "nostrike":
attrs = attrs._replace(strike=False)
- # prompt_toolkit extensions. Not in Pygments.
elif part == "blink":
attrs = attrs._replace(blink=True)
elif part == "noblink":
@@ -150,18 +139,14 @@ def _parse_style_str(style_str: str) -> Attrs:
elif part == "nohidden":
attrs = attrs._replace(hidden=False)
- # Pygments properties that we ignore.
elif part in ("roman", "sans", "mono"):
pass
elif part.startswith("border:"):
pass
- # Ignore pieces in between square brackets. This is internal stuff.
- # Like '[transparent]' or '[set-cursor-position]'.
elif part.startswith("[") and part.endswith("]"):
pass
- # Colors.
elif part.startswith("bg:"):
attrs = attrs._replace(bgcolor=parse_color(part[3:]))
elif part.startswith("fg:"): # The 'fg:' prefix is optional.
@@ -291,9 +276,7 @@ def get_attrs_for_style_str(
for new_name in new_class_names:
# Build a set of all possible class combinations to be applied.
- combos = set()
- combos.add(frozenset([new_name]))
-
+ combos = {frozenset([new_name])}
for count in range(1, len(class_names) + 1):
for c2 in itertools.combinations(class_names, count):
combos.add(frozenset(c2 + (new_name,)))
@@ -305,7 +288,6 @@ def get_attrs_for_style_str(
class_names.add(new_name)
- # Process inline style.
else:
inline_attrs = _parse_style_str(part)
list_of_attrs.append(inline_attrs)
diff --git a/src/prompt_toolkit/styles/style_transformation.py b/src/prompt_toolkit/styles/style_transformation.py
index 91308f9127..dc38358a80 100644
--- a/src/prompt_toolkit/styles/style_transformation.py
+++ b/src/prompt_toolkit/styles/style_transformation.py
@@ -203,7 +203,7 @@ def _color_to_rgb(self, color: str) -> Tuple[float, float, float]:
# Parse RRGGBB format.
return (
- int(color[0:2], 16) / 255.0,
+ int(color[:2], 16) / 255.0,
int(color[2:4], 16) / 255.0,
int(color[4:6], 16) / 255.0,
)
diff --git a/src/prompt_toolkit/utils.py b/src/prompt_toolkit/utils.py
index 4ceded34c4..2cbddd367a 100644
--- a/src/prompt_toolkit/utils.py
+++ b/src/prompt_toolkit/utils.py
@@ -250,7 +250,7 @@ def take_using_weights(
integers, not floats.)
"""
assert len(items) == len(weights)
- assert len(items) > 0
+ assert items
# Remove items with zero-weight.
items2 = []
@@ -268,7 +268,7 @@ def take_using_weights(
raise ValueError("Did't got any items with a positive weight.")
#
- already_taken = [0 for i in items]
+ already_taken = [0 for _ in items]
item_count = len(items)
max_weight = max(weights)
@@ -290,18 +290,12 @@ def take_using_weights(
def to_str(value: Union[Callable[[], str], str]) -> str:
"Turn callable or string into string."
- if callable(value):
- return to_str(value())
- else:
- return str(value)
+ return to_str(value()) if callable(value) else str(value)
def to_int(value: Union[Callable[[], int], int]) -> int:
"Turn callable or int into int."
- if callable(value):
- return to_int(value())
- else:
- return int(value)
+ return to_int(value()) if callable(value) else int(value)
AnyFloat = Union[Callable[[], float], float]
@@ -309,10 +303,7 @@ def to_int(value: Union[Callable[[], int], int]) -> int:
def to_float(value: AnyFloat) -> float:
"Turn callable or float into float."
- if callable(value):
- return to_float(value())
- else:
- return float(value)
+ return to_float(value()) if callable(value) else float(value)
def is_dumb_terminal(term: Optional[str] = None) -> bool:
diff --git a/src/prompt_toolkit/validation.py b/src/prompt_toolkit/validation.py
index 8bdffff524..8896d72d55 100644
--- a/src/prompt_toolkit/validation.py
+++ b/src/prompt_toolkit/validation.py
@@ -118,11 +118,7 @@ def __repr__(self) -> str:
def validate(self, document: Document) -> None:
if not self.func(document.text):
- if self.move_cursor_to_end:
- index = len(document.text)
- else:
- index = 0
-
+ index = len(document.text) if self.move_cursor_to_end else 0
raise ValidationError(cursor_position=index, message=self.error_message)
diff --git a/src/prompt_toolkit/widgets/base.py b/src/prompt_toolkit/widgets/base.py
index bd2d332209..f3d1230178 100644
--- a/src/prompt_toolkit/widgets/base.py
+++ b/src/prompt_toolkit/widgets/base.py
@@ -248,20 +248,14 @@ def __init__(
)
if multiline:
- if scrollbar:
- right_margins = [ScrollbarMargin(display_arrows=True)]
- else:
- right_margins = []
- if line_numbers:
- left_margins = [NumberedMargin()]
- else:
- left_margins = []
+ right_margins = [ScrollbarMargin(display_arrows=True)] if scrollbar else []
+ left_margins = [NumberedMargin()] if line_numbers else []
else:
height = D.exact(1)
left_margins = []
right_margins = []
- style = "class:text-area " + style
+ style = f"class:text-area {style}"
# If no height was given, guarantee height of at least 1.
if height is None:
@@ -352,16 +346,14 @@ def __init__(
self.text = text
def get_width() -> AnyDimension:
- if width is None:
- text_fragments = to_formatted_text(self.text)
- text = fragment_list_to_text(text_fragments)
- if text:
- longest_line = max(get_cwidth(line) for line in text.splitlines())
- else:
- return D(preferred=0)
- return D(preferred=longest_line)
- else:
+ if width is not None:
return width
+ text_fragments = to_formatted_text(self.text)
+ if text := fragment_list_to_text(text_fragments):
+ longest_line = max(get_cwidth(line) for line in text.splitlines())
+ else:
+ return D(preferred=0)
+ return D(preferred=longest_line)
self.formatted_text_control = FormattedTextControl(text=lambda: self.text)
@@ -858,11 +850,7 @@ def __init__(
values: Sequence[Tuple[_T, AnyFormattedText]],
default: Optional[_T] = None,
) -> None:
- if default is None:
- default_values = None
- else:
- default_values = [default]
-
+ default_values = None if default is None else [default]
super().__init__(values, default_values=default_values)
@@ -901,10 +889,7 @@ def checked(self) -> bool:
@checked.setter
def checked(self, value: bool) -> None:
- if value:
- self.current_values = ["value"]
- else:
- self.current_values = []
+ self.current_values = ["value"] if value else []
class VerticalLine:
@@ -943,10 +928,6 @@ def __init__(self) -> None:
self.container = FloatContainer(
content=Window(height=1),
floats=[
- # We first draw the label, then the actual progress bar. Right
- # now, this is the only way to have the colors of the progress
- # bar appear on top of the label. The problem is that our label
- # can't be part of any `Window` below.
Float(content=self.label, top=0, bottom=0),
Float(
left=0,
@@ -957,11 +938,13 @@ def __init__(self) -> None:
[
Window(
style="class:progress-bar.used",
- width=lambda: D(weight=int(self._percentage)),
+ width=lambda: D(weight=self._percentage),
),
Window(
style="class:progress-bar",
- width=lambda: D(weight=int(100 - self._percentage)),
+ width=lambda: D(
+ weight=int(100 - self._percentage)
+ ),
),
]
),
diff --git a/src/prompt_toolkit/widgets/menus.py b/src/prompt_toolkit/widgets/menus.py
index 6827ebecc7..f099afa0a9 100644
--- a/src/prompt_toolkit/widgets/menus.py
+++ b/src/prompt_toolkit/widgets/menus.py
@@ -115,13 +115,11 @@ def _up_in_submenu(event: E) -> None:
menu = self._get_menu(len(self.selected_menu) - 2)
index = self.selected_menu[-1]
- previous_indexes = [
+ if previous_indexes := [
i
for i, item in enumerate(menu.children)
if i < index and not item.disabled
- ]
-
- if previous_indexes:
+ ]:
self.selected_menu[-1] = previous_indexes[-1]
elif len(self.selected_menu) == 2:
# Return to main menu.
@@ -133,13 +131,11 @@ def _down_in_submenu(event: E) -> None:
menu = self._get_menu(len(self.selected_menu) - 2)
index = self.selected_menu[-1]
- next_indexes = [
+ if next_indexes := [
i
for i, item in enumerate(menu.children)
if i > index and not item.disabled
- ]
-
- if next_indexes:
+ ]:
self.selected_menu[-1] = next_indexes[0]
@kb.add("enter")
@@ -368,7 +364,4 @@ def __init__(
@property
def width(self) -> int:
- if self.children:
- return max(get_cwidth(c.text) for c in self.children)
- else:
- return 0
+ return max(get_cwidth(c.text) for c in self.children) if self.children else 0
diff --git a/src/prompt_toolkit/widgets/toolbars.py b/src/prompt_toolkit/widgets/toolbars.py
index 402ecaa982..c126f65d7f 100644
--- a/src/prompt_toolkit/widgets/toolbars.py
+++ b/src/prompt_toolkit/widgets/toolbars.py
@@ -346,23 +346,19 @@ def __init__(self, show_position: bool = False) -> None:
def get_formatted_text() -> StyleAndTextTuples:
buff = get_app().current_buffer
- if buff.validation_error:
- row, column = buff.document.translate_index_to_position(
- buff.validation_error.cursor_position
- )
+ if not buff.validation_error:
+ return []
+ row, column = buff.document.translate_index_to_position(
+ buff.validation_error.cursor_position
+ )
- if show_position:
- text = "{} (line={} column={})".format(
- buff.validation_error.message,
- row + 1,
- column + 1,
- )
- else:
- text = buff.validation_error.message
+ text = (
+ f"{buff.validation_error.message} (line={row + 1} column={column + 1})"
+ if show_position
+ else buff.validation_error.message
+ )
- return [("class:validation-toolbar", text)]
- else:
- return []
+ return [("class:validation-toolbar", text)]
self.control = FormattedTextControl(get_formatted_text)
diff --git a/tests/test_buffer.py b/tests/test_buffer.py
index 413ec98743..1edc40d6e9 100644
--- a/tests/test_buffer.py
+++ b/tests/test_buffer.py
@@ -5,8 +5,7 @@
@pytest.fixture
def _buffer():
- buff = Buffer()
- return buff
+ return Buffer()
def test_initial(_buffer):
diff --git a/tests/test_completion.py b/tests/test_completion.py
index 26f6644cd4..539229ada8 100644
--- a/tests/test_completion.py
+++ b/tests/test_completion.py
@@ -42,7 +42,7 @@ def test_pathcompleter_completes_in_current_directory():
doc = Document(doc_text, len(doc_text))
event = CompleteEvent()
completions = list(completer.get_completions(doc, event))
- assert len(completions) > 0
+ assert completions
def test_pathcompleter_completes_files_in_current_directory():
@@ -203,7 +203,7 @@ def test_pathcompleter_can_expanduser():
doc = Document(doc_text, len(doc_text))
event = CompleteEvent()
completions = list(completer.get_completions(doc, event))
- assert len(completions) > 0
+ assert completions
def test_pathcompleter_can_apply_file_filter():
@@ -268,7 +268,7 @@ def test_word_completer_static_word_list():
assert [c.text for c in completions] == ["abc", "aaa"]
completions = completer.get_completions(Document("A"), CompleteEvent())
- assert [c.text for c in completions] == []
+ assert not [c.text for c in completions]
# Multiple words ending with space. (Accept all options)
completions = completer.get_completions(Document("test "), CompleteEvent())
@@ -342,7 +342,7 @@ def test_word_completer_pattern():
# Without pattern
completer = WordCompleter(["abc", "a.b.c", "a.b", "xyz"])
completions = completer.get_completions(Document("a."), CompleteEvent())
- assert [c.text for c in completions] == []
+ assert not [c.text for c in completions]
def test_fuzzy_completer():
diff --git a/tests/test_regular_languages.py b/tests/test_regular_languages.py
index 7404b231a4..ca74a541b8 100644
--- a/tests/test_regular_languages.py
+++ b/tests/test_regular_languages.py
@@ -76,13 +76,13 @@ def test_prefix():
def test_completer():
class completer1(Completer):
def get_completions(self, document, complete_event):
- yield Completion("before-%s-after" % document.text, -len(document.text))
- yield Completion("before-%s-after-B" % document.text, -len(document.text))
+ yield Completion(f"before-{document.text}-after", -len(document.text))
+ yield Completion(f"before-{document.text}-after-B", -len(document.text))
class completer2(Completer):
def get_completions(self, document, complete_event):
- yield Completion("before2-%s-after2" % document.text, -len(document.text))
- yield Completion("before2-%s-after2-B" % document.text, -len(document.text))
+ yield Completion(f"before2-{document.text}-after2", -len(document.text))
+ yield Completion(f"before2-{document.text}-after2-B", -len(document.text))
# Create grammar. "var1" + "whitespace" + "var2"
g = compile(r"(?P[a-z]*) \s+ (?P[a-z]*)")