This commit is contained in:
Tyrel Souza 2022-01-02 22:31:10 -05:00
parent 77a090ff1c
commit 20a1ae6d39
13 changed files with 395 additions and 55 deletions

95
Session.vim Normal file
View File

@ -0,0 +1,95 @@
let SessionLoad = 1
let s:so_save = &g:so | let s:siso_save = &g:siso | setg so=0 siso=0 | setl so=-1 siso=-1
let v:this_session=expand("<sfile>:p")
silent only
silent tabonly
cd ~/code/python/rogueliketutorials
if expand('%') == '' && !&modified && line('$') <= 1 && getline(1) == ''
let s:wipebuf = bufnr('%')
endif
set shortmess=aoO
argglobal
%argdel
edit render_functions.py
let s:save_splitbelow = &splitbelow
let s:save_splitright = &splitright
set splitbelow splitright
wincmd _ | wincmd |
vsplit
1wincmd h
wincmd w
let &splitbelow = s:save_splitbelow
let &splitright = s:save_splitright
wincmd t
let s:save_winminheight = &winminheight
let s:save_winminwidth = &winminwidth
set winminheight=0
set winheight=1
set winminwidth=0
set winwidth=1
exe 'vert 1resize ' . ((&columns * 103 + 72) / 144)
exe 'vert 2resize ' . ((&columns * 40 + 72) / 144)
argglobal
balt render_order.py
setlocal fdm=manual
setlocal fde=0
setlocal fmr={{{,}}}
setlocal fdi=#
setlocal fdl=0
setlocal fml=1
setlocal fdn=20
setlocal fen
silent! normal! zE
let &fdl = &fdl
let s:l = 8 - ((7 * winheight(0) + 28) / 56)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 8
normal! 032|
wincmd w
argglobal
enew
file __Tagbar__.1
setlocal fdm=manual
setlocal fde=0
setlocal fmr={{{,}}}
setlocal fdi=#
setlocal fdl=0
setlocal fml=1
setlocal fdn=20
setlocal nofen
wincmd w
exe 'vert 1resize ' . ((&columns * 103 + 72) / 144)
exe 'vert 2resize ' . ((&columns * 40 + 72) / 144)
if exists(':tcd') == 2 | tcd ~/code/python/rogueliketutorials | endif
tabnext 1
badd +40 ~/code/python/rogueliketutorials/components/ai.py
badd +73 ~/code/python/rogueliketutorials/game_map.py
badd +59 ~/code/python/rogueliketutorials/input_handlers.py
badd +86 ~/code/python/rogueliketutorials/entity.py
badd +1 ~/code/python/rogueliketutorials/main.py
badd +3 ~/code/python/rogueliketutorials/actions.py
badd +26 ~/code/python/rogueliketutorials/engine.py
badd +1 ~/code/python/rogueliketutorials/entity_factories.py
badd +47 ~/code/python/rogueliketutorials/components/fighter.py
badd +3 ~/code/python/rogueliketutorials/render_order.py
badd +14 ~/code/python/rogueliketutorials/color.py
badd +22 ~/code/python/rogueliketutorials/render_functions.py
badd +59 ~/code/python/rogueliketutorials/message_log.py
if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'
silent exe 'bwipe ' . s:wipebuf
endif
unlet! s:wipebuf
set winheight=1 winwidth=20 shortmess=filnxtToOFI
let &winminheight = s:save_winminheight
let &winminwidth = s:save_winminwidth
let s:sx = expand("<sfile>:p:r")."x.vim"
if filereadable(s:sx)
exe "source " . fnameescape(s:sx)
endif
let &g:so = s:so_save | let &g:siso = s:siso_save
set hlsearch
doautoall SessionLoadPost
unlet SessionLoad
" vim: set ft=vim :

View File

@ -1,5 +1,6 @@
from __future__ import annotations
from typing import Optional, Tuple, TYPE_CHECKING
import color
if TYPE_CHECKING:
from engine import Engine
@ -13,7 +14,7 @@ class Action:
@property
def engine(self) -> Engine:
return self.entity.gamemap.engine
return self.entity.game_map.engine
def perform(self) -> None:
"""Perform this action with the objects needed to determine its scope.
@ -49,11 +50,11 @@ class ActionWithDirection(Action):
@property
def target_actor(self) -> Optional[Actor]:
return self.engine.gamemap.get_actor_at_location(*self.dest_xy)
return self.engine.game_map.get_actor_at_location(*self.dest_xy)
@property
def blocking_entity(self) -> Optional[Entity]:
return self.engine.gamemap.get_blocking_entity_at_location(*self.dest_xy)
return self.engine.game_map.get_blocking_entity_at_location(*self.dest_xy)
def perform(self) -> None:
raise NotImplementedError()
@ -67,22 +68,31 @@ class MeleeAction(ActionWithDirection):
damage = self.entity.fighter.power - target.fighter.defense
attack_desc = f"{self.entity.name.capitalize()} attacks {target.name}"
if self.entity is self.engine.player:
attack_color = color.player_atk
else:
attack_color = color.enemy_atk
if damage > 0:
print(f"{attack_desc} for {damage} hit points.")
self.engine.message_log.add_message(
f"{attack_desc} for {damage} hit points."
)
target.fighter.hp -= damage
else:
print(f"{attack_desc} but does no damage.")
self.engine.message_log.add_message(
f"{attack_desc} but does no damage."
)
class MovementAction(ActionWithDirection):
def perform(self) -> None:
dest_x, dest_y = self.dest_xy
if not self.engine.gamemap.in_bounds(dest_x, dest_y):
if not self.engine.game_map.in_bounds(dest_x, dest_y):
return # OOB
if not self.engine.gamemap.tiles["walkable"][dest_x, dest_y]:
if not self.engine.game_map.tiles["walkable"][dest_x, dest_y]:
return # can't walk
if self.engine.gamemap.get_blocking_entity_at_location(dest_x, dest_y):
if self.engine.game_map.get_blocking_entity_at_location(dest_x, dest_y):
return # Blocked
self.entity.move(self.dx, self.dy)

14
color.py Normal file
View File

@ -0,0 +1,14 @@
white = (0xFF, 0xFF, 0xFF)
black = (0x0, 0x0, 0x0)
player_atk = (0xE0, 0xE0, 0xE0)
enemy_atk = (0xFF, 0xC0, 0xC0)
player_die = (0xFF, 0x30, 0x30)
enemy_die = (0xFF, 0xA0, 0x30)
welcome_text = (0x20, 0xA0, 0xFF)
bar_text = white
bar_filled = (0x0, 0x60, 0x0)
bar_empty = (0x40, 0x10, 0x10)

View File

@ -20,8 +20,8 @@ class BaseAI(Action, BaseComponent):
def get_path_to(self, dest_x: int, dest_y: int) -> List[Tuple[int, int]]:
"""computer and return path"""
cost = np.array(self.entity.gamemap.tiles["walkable"], dtype=np.int8)
for entity in self.entity.gamemap.entities:
cost = np.array(self.entity.game_map.tiles["walkable"], dtype=np.int8)
for entity in self.entity.game_map.entities:
# Check that an enitiy blocks movement and the cost isn't zero (blocking.)
if entity.blocks_movement and cost[entity.x, entity.y]:
# Add to the cost of a blocked position.
@ -51,7 +51,7 @@ class HostileEnemy(BaseAI):
dy = target.y - self.entity.y
distance = max(abs(dx), abs(dy))
if self.engine.gamemap.visible[self.entity.x, self.entity.y]:
if self.engine.game_map.visible[self.entity.x, self.entity.y]:
if distance <= 1:
return MeleeAction(self.entity, dx, dy).perform()

View File

@ -11,4 +11,4 @@ class BaseComponent:
@property
def engine(self) -> Engine:
return self.entity.gamemap.engine
return self.entity.game_map.engine

View File

@ -1,6 +1,7 @@
from __future__ import annotations
from typing import TYPE_CHECKING
import color
from components.base_components import BaseComponent
from input_handlers import GameOverEventHandler
from render_order import RenderOrder
@ -30,9 +31,11 @@ class Fighter(BaseComponent):
def die(self) -> None:
if self.engine.player is self.entity:
death_message = "You died."
death_message_color = color.player_die
self.engine.event_handler = GameOverEventHandler(self.engine)
else:
death_message = f"{self.entity.name} is dead!"
death_message_color = color.player_die
self.entity.char = "%"
self.entity.color = (191,0,0)
@ -41,4 +44,4 @@ class Fighter(BaseComponent):
self.entity.name = f"remains of {self.entity.name}"
self.entity.render_order = RenderOrder.CORPSE
print(death_message)
self.engine.message_log.add_message(death_message, death_message_color)

View File

@ -1,11 +1,12 @@
from __future__ import annotations
from typing import TYPE_CHECKING
from tcod.context import Context
from tcod.console import Console
from tcod.map import compute_fov
from input_handlers import MainGameEventHandler
from message_log import MessageLog
from render_functions import render_bar, render_names_at_mouse_location
if TYPE_CHECKING:
from entity import Actor
@ -14,33 +15,37 @@ if TYPE_CHECKING:
class Engine:
gamemap: GameMap
game_map: GameMap
def __init__(self, player: Actor):
self.event_handler: EventHandler = MainGameEventHandler(self)
self.message_log = MessageLog()
self.mouse_location = (0,0)
self.player = player
def handle_enemy_turns(self) -> None:
for entity in set(self.gamemap.actors) - {self.player}:
for entity in set(self.game_map.actors) - {self.player}:
if entity.ai:
entity.ai.perform()
def update_fov(self) -> None:
self.gamemap.visible[:] = compute_fov(
self.gamemap.tiles["transparent"],
self.game_map.visible[:] = compute_fov(
self.game_map.tiles["transparent"],
(self.player.x, self.player.y),
radius=8,
)
self.gamemap.explored |= self.gamemap.visible
self.game_map.explored |= self.game_map.visible
def render(self, console: Console, context: Context) -> None:
self.gamemap.render(console)
def render(self, console: Console) -> None:
self.game_map.render(console)
console.print(
x=1,
y=47,
string=f"HP: {self.player.fighter.hp}/{self.player.fighter.max_hp}",
self.message_log.render(console=console, x=21, y=45, width=40, height=5)
render_bar(
console=console,
current_value=self.player.fighter.hp,
maximum_value=self.player.fighter.max_hp,
total_width=20,
)
context.present(console)
console.clear()
render_names_at_mouse_location(console, x=21, y=44, engine=self)

View File

@ -18,11 +18,11 @@ class Entity:
A generic object to represent players, enemies, items, etc.
"""
gamemap: GameMap
game_map: GameMap
def __init__(
self,
gamemap: Optional[GameMap] = None,
game_map: Optional[GameMap] = None,
x: int = 0,
y: int = 0,
char: str = "?",
@ -38,27 +38,27 @@ class Entity:
self.name = name
self.blocks_movement = blocks_movement
self.render_order = render_order
if gamemap:
self.gamemap = gamemap
gamemap.entities.add(self)
if game_map:
self.game_map = game_map
game_map.entities.add(self)
def spawn(self: T, gamemap: GameMap, x: int, y: int) -> T:
def spawn(self: T, game_map: GameMap, x: int, y: int) -> T:
"""Spawns a copy of this instance at the given location"""
clone = copy.deepcopy(self)
clone.x = x
clone.y = y
clone.gamemap = gamemap
gamemap.entities.add(clone)
clone.game_map = game_map
game_map.entities.add(clone)
return clone
def place(self, x: int, y: int, gamemap: Optional[GameMap] = None) -> None:
def place(self, x: int, y: int, game_map: Optional[GameMap] = None) -> None:
self.x = x
self.y = y
if gamemap:
if hasattr(self, "gamemap"):
self.gamemap.entities.remove(self)
self.gamemap = gamemap
gamemap.entities.add(self)
if game_map:
if hasattr(self, "game_map"):
self.game_map.entities.remove(self)
self.game_map = game_map
game_map.entities.add(self)
def move(self, dx: int, dy: int) -> None:
self.x += dx

View File

@ -43,22 +43,38 @@ WAIT_KEYS = {
tcod.event.K_KP_5,
tcod.event.K_CLEAR,
}
CURSOR_Y_KEYS = {
tcod.event.K_UP: -1,
tcod.event.K_DOWN: 1,
tcod.event.K_PAGEUP: -10,
tcod.event.K_PAGEDOWN: 10,
}
class EventHandler(tcod.event.EventDispatch[Action]):
def __init__(self, engine: Engine):
self.engine = engine
def handle_events(self) -> None:
raise NotImplementedError()
def handle_events(self, context: tcode.context.Context) -> None:
for event in tcod.event.wait():
context.convert_event(event)
self.dispatch(event)
def ev_mousemotion(self, event: tcod.event.MouseMotion) -> None:
if self.engine.game_map.in_bounds(event.tile.x, event.tile.y):
self.engine.mouse_location = event.tile.x, event.tile.y
def ev_quit(self, event: tcod.event.Quit) -> Optional[Action]:
raise SystemExit()
def on_render(self, console: tcod.Console) -> None:
self.engine.render(console)
class MainGameEventHandler(EventHandler):
def handle_events(self) -> None:
def handle_events(self, context: tcod.context.Context) -> None:
for event in tcod.event.wait():
context.convert_event(event)
action = self.dispatch(event)
if action is None:
@ -79,11 +95,14 @@ class MainGameEventHandler(EventHandler):
action = BumpAction(player, dx, dy)
elif key == WAIT_KEYS:
action = WaitAction(player)
elif key == tcod.event.K_v:
self.engine.event_handler = HistoryViewer(self.engine)
return action
class GameOverEventHandler(EventHandler):
def handle_events(self) -> None:
def handle_events(self, context: tcod.context.Context) -> None:
for event in tcod.event.wait():
action = self.dispatch(event)
@ -101,3 +120,44 @@ class GameOverEventHandler(EventHandler):
action = EscapeAction(self.engine.player)
return action
class HistoryViewer(EventHandler):
def __init__(self, engine: Engine):
super().__init__(engine)
self.log_length = len(engine.message_log.messages)
self.cursor = self.log_length - 1
def on_render(self, console: tcod.Console)-> None:
super().on_render(console)
log_console = tcod.Console(console.width -6, console.height-6)
# Draw a frame with a custom banner title.
log_console.draw_frame(0, 0, log_console.width, log_console.height)
log_console.print_box(
0, 0, log_console.width, 1, "┤Message history├", alignment=tcod.CENTER
)
self.engine.message_log.render_messages(
log_console,
1,
1,
log_console.width - 2,
log_console.height - 2,
self.engine.message_log.messages[: self.cursor + 1],
)
log_console.blit(console, 3, 3)
def ev_keydown(self, event: tcod.event.KeyDown) -> None:
if event.sym in CURSOR_Y_KEYS:
adjust = CURSOR_Y_KEYS[event.sym]
if adjust < 0 and self.cursor == 0:
self.cursor = self.log_length - 1
elif adjust > 0 and self.cursor == self.log_length - 1:
self.cursor = 0
else:
self.cursor = max(0, min(self.cursor + adjust, self.log_length - 1))
elif event.sym == tcod.event.K_HOME:
self.cursor = 0 # Move directly to the top message.
elif event.sym == tcod.event.K_END:
self.cursor = self.log_length - 1 # Move directly to the last message.
else: # Any other key moves back to the main game state.
self.engine.event_handler = MainGameEventHandler(self.engine)

16
main.py
View File

@ -3,6 +3,7 @@ import tcod
import copy
import entity_factories
import color
from engine import Engine
from input_handlers import EventHandler
from procgen import generate_dungeon
@ -13,7 +14,7 @@ def main():
screen_height = 50
map_width = 80
map_height = 45
map_height = 43
room_max_size = 10
room_min_size = 6
@ -28,7 +29,7 @@ def main():
player = copy.deepcopy(entity_factories.player)
engine = Engine(player=player)
engine.gamemap = generate_dungeon(
engine.game_map = generate_dungeon(
max_rooms=max_rooms,
room_min_size=room_min_size,
room_max_size=room_max_size,
@ -39,6 +40,10 @@ def main():
)
engine.update_fov()
engine.message_log.add_message(
"Hello and welcome, adventurer, to yet another dungeon", color.welcome_text
)
with tcod.context.new_terminal(
screen_width,
screen_height,
@ -48,8 +53,11 @@ def main():
) as context:
root_console = tcod.Console(screen_width, screen_height, order="F")
while True:
engine.render(console=root_console, context=context)
engine.event_handler.handle_events()
root_console.clear()
engine.event_handler.on_render(console=root_console)
context.present(root_console)
engine.event_handler.handle_events(context)
if __name__ == "__main__":

63
message_log.py Normal file
View File

@ -0,0 +1,63 @@
from typing import List, Reversible, Tuple
import textwrap
import tcod
import color
class Message:
def __init__(self, text: str, fg: Tuple[int, int, int]):
self.plain_text = text
self.fg = fg
self.count = 1
@property
def full_text(self) -> str:
"""The full text of this message, including the count if necessary."""
if self.count > 1:
return f"{self.plain_text} (x{self.count})"
return self.plain_text
class MessageLog:
def __init__(self) -> None:
self.messages: List[Message] = []
def add_message(
self,
text: str,
fg: Tuple[int, int, int] = color.white,
*,
stack: bool = True,
) -> None:
if stack and self.messages and text == self.messages[-1].plain_text:
self.messages[-1].count += 1
else:
self.messages.append(Message(text, fg))
def render(
self,
console: tcod.Console,
x: int,
y: int,
width: int,
height: int,
) -> None:
self.render_messages(console, x, y, width, height, self.messages)
@staticmethod
def render_messages(
console: tcod.Console,
x: int,
y: int,
width: int,
height: int,
messages: Reversible[Message],
) -> None:
y_offset = height - 1
for message in reversed(messages):
for line in reversed(textwrap.wrap(message.full_text, width)):
console.print(x=x, y=y + y_offset, string=line, fg=message.fg)
y_offset -= 1
if y_offset < 0:
return

45
render_functions.py Normal file
View File

@ -0,0 +1,45 @@
from __future__ import annotations
from typing import TYPE_CHECKING
import color
if TYPE_CHECKING:
from tcod import Console
from engine import Engine
from game_map import GameMap
def get_names_at_location(x: int, y: int, game_map: GameMap) -> str:
if not game_map.in_bounds(x,y) or not game_map.visible[x,y]:
return ""
names = ", ".join(
entity.name for entity in game_map.entities if entity.x == x and entity.y == y
)
return names.capitalize()
def render_bar(
console: Console, current_value: int, maximum_value: int, total_width: int
) -> None:
bar_width = int(float(current_value) / maximum_value * total_width)
console.draw_rect(x=0, y=45, width=20, height=1, ch=1, bg=color.bar_empty)
if bar_width > 0:
console.draw_rect(
x=0, y=45, width=bar_width, height=1, ch=1, bg=color.bar_filled
)
console.print(
x=1, y=45, string=f"HP: {current_value}/{maximum_value}", fg=color.bar_text
)
def render_names_at_mouse_location(
console: Console, x: int, y: int, engine: Engine
) -> None:
mouse_x, mouse_y = engine.mouse_location
names_at_mouse_location = get_names_at_location(
x=mouse_x, y=mouse_y, game_map=engine.game_map
)
console.print(x=x,y=y, string=names_at_mouse_location)

49
tags
View File

@ -943,6 +943,7 @@ CURRENCYSUBUNIT venv/lib/python3.10/site-packages/tcod/event.py /^ CURRENCYSU
CURRENCYSUBUNIT venv/lib/python3.10/site-packages/tcod/event.py /^ CURRENCYSUBUNIT = 181$/;" v class:Scancode
CURRENCYUNIT venv/lib/python3.10/site-packages/tcod/event.py /^ CURRENCYUNIT = 1073742004$/;" v class:KeySym
CURRENCYUNIT venv/lib/python3.10/site-packages/tcod/event.py /^ CURRENCYUNIT = 180$/;" v class:Scancode
CURSOR_Y_KEYS input_handlers.py /^CURSOR_Y_KEYS = {$/;" v
CUT venv/lib/python3.10/site-packages/tcod/event.py /^ CUT = 1073741947$/;" v class:KeySym
CUT venv/lib/python3.10/site-packages/tcod/event.py /^ CUT = 123$/;" v class:Scancode
CYAN venv/lib/python3.10/site-packages/pip/_vendor/colorama/ansi.py /^ CYAN = 36$/;" v class:AnsiFore
@ -2146,6 +2147,7 @@ HermitianTestCase venv/lib/python3.10/site-packages/numpy/linalg/tests/test_lina
Hexnumber venv/lib/python3.10/site-packages/blib2to3/pgen2/tokenize.py /^Hexnumber = r"0[xX]_?[\\da-fA-F]+(?:_[\\da-fA-F]+)*[lL]?"$/;" v
HiddenText venv/lib/python3.10/site-packages/pip/_internal/utils/misc.py /^class HiddenText:$/;" c
Hiragana venv/lib/python3.10/site-packages/pip/_vendor/pyparsing.py /^ class Hiragana(unicode_set):$/;" c class:pyparsing_unicode.Japanese
HistoryViewer input_handlers.py /^class HistoryViewer(EventHandler):$/;" c
Hlist venv/lib/python3.10/site-packages/numpy/polynomial/tests/test_hermite.py /^Hlist = [H0, H1, H2, H3, H4, H5, H6, H7, H8, H9]$/;" v
HookMissing venv/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py /^class HookMissing(Exception):$/;" c
HookMissing venv/lib/python3.10/site-packages/pip/_vendor/pep517/wrappers.py /^class HookMissing(Exception):$/;" c
@ -3404,6 +3406,8 @@ MemmapSubClass venv/lib/python3.10/site-packages/numpy/core/tests/test_memmap.py
MemoizedZipManifests venv/lib/python3.10/site-packages/pip/_vendor/pkg_resources/__init__.py /^class MemoizedZipManifests(ZipManifests):$/;" c
MemoizedZipManifests venv/lib/python3.10/site-packages/pkg_resources/__init__.py /^class MemoizedZipManifests(ZipManifests):$/;" c
Mercurial venv/lib/python3.10/site-packages/pip/_internal/vcs/mercurial.py /^class Mercurial(VersionControl):$/;" c
Message message_log.py /^class Message:$/;" c
MessageLog message_log.py /^class MessageLog:$/;" c
Metadata venv/lib/python3.10/site-packages/pip/_vendor/distlib/metadata.py /^class Metadata(object):$/;" c
MetadataConflictError venv/lib/python3.10/site-packages/pip/_vendor/distlib/metadata.py /^class MetadataConflictError(DistlibException):$/;" c
MetadataInconsistent venv/lib/python3.10/site-packages/pip/_internal/exceptions.py /^class MetadataInconsistent(InstallationError):$/;" c
@ -6651,6 +6655,7 @@ Serializer venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/serialize.
ServerProxy venv/lib/python3.10/site-packages/pip/_vendor/distlib/util.py /^class ServerProxy(xmlrpclib.ServerProxy):$/;" c
Session venv/lib/python3.10/site-packages/pip/_vendor/requests/sessions.py /^class Session(SessionRedirectMixin):$/;" c
SessionCommandMixin venv/lib/python3.10/site-packages/pip/_internal/cli/req_command.py /^class SessionCommandMixin(CommandContextMixIn):$/;" c
SessionLoad Session.vim /^let SessionLoad = 1$/;" v
SessionRedirectMixin venv/lib/python3.10/site-packages/pip/_vendor/requests/sessions.py /^class SessionRedirectMixin(object):$/;" c
SetConsoleCursorPosition venv/lib/python3.10/site-packages/pip/_vendor/colorama/win32.py /^ def SetConsoleCursorPosition(stream_id, position, adjust=True):$/;" f
SetConsoleTextAttribute venv/lib/python3.10/site-packages/pip/_vendor/colorama/win32.py /^ SetConsoleTextAttribute = lambda *_: None$/;" f
@ -10392,6 +10397,9 @@ __init__ entity.py /^ def __init__($/;" m class:Actor
__init__ entity.py /^ def __init__($/;" m class:Entity
__init__ game_map.py /^ def __init__($/;" m class:GameMap
__init__ input_handlers.py /^ def __init__(self, engine: Engine):$/;" m class:EventHandler
__init__ input_handlers.py /^ def __init__(self, engine: Engine):$/;" m class:HistoryViewer
__init__ message_log.py /^ def __init__(self) -> None:$/;" m class:MessageLog typeref:typename:None
__init__ message_log.py /^ def __init__(self, text: str, fg: Tuple[int, int, int]):$/;" m class:Message
__init__ procgen.py /^ def __init__(self, x: int, y: int, width: int, height: int):$/;" m class:RectangularRoom
__init__ venv/lib/python3.10/site-packages/black/handle_ipynb_magics.py /^ def __init__(self) -> None:$/;" m class:MagicFinder typeref:typename:None
__init__ venv/lib/python3.10/site-packages/black/handle_ipynb_magics.py /^ def __init__(self, cell_magic: Optional[CellMagic] = None) -> None:$/;" m class:CellMagicFinder typeref:typename:None
@ -17102,6 +17110,7 @@ add_license_files venv/lib/python3.10/site-packages/setuptools/command/egg_info.
add_link_object venv/lib/python3.10/site-packages/setuptools/_distutils/ccompiler.py /^ def add_link_object(self, object):$/;" m class:CCompiler
add_lookaheads venv/lib/python3.10/site-packages/pycparser/ply/yacc.py /^ def add_lookaheads(self, lookbacks, followset):$/;" m class:LRGeneratedTable
add_many venv/lib/python3.10/site-packages/pip/_vendor/distlib/manifest.py /^ def add_many(self, items):$/;" m class:Manifest
add_message message_log.py /^ def add_message($/;" m class:MessageLog typeref:typename:None
add_metaclass venv/lib/python3.10/site-packages/pip/_vendor/six.py /^def add_metaclass(metaclass):$/;" f
add_metaclass venv/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/six.py /^def add_metaclass(metaclass):$/;" f
add_method venv/lib/python3.10/site-packages/numpy/core/tests/test_overrides.py /^ def add_method(self, name, arr_class, enable_value_error=False):$/;" m class:TestArrayLike
@ -17866,12 +17875,15 @@ bar venv/lib/python3.10/site-packages/numpy/lib/tests/test_function_base.py /^
bar11 venv/lib/python3.10/site-packages/numpy/f2py/tests/src/mixed/foo.f /^ subroutine bar11(/;" s
bar12 venv/lib/python3.10/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90 /^ subroutine bar12(/;" s module:foo_fixed
bar13 venv/lib/python3.10/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90 /^ subroutine bar13(/;" s module:foo_free
bar_empty color.py /^bar_empty = (0x40, 0x10, 0x10)$/;" v
bar_filled color.py /^bar_filled = (0x0, 0x60, 0x0)$/;" v
bar_prefix venv/lib/python3.10/site-packages/pip/_internal/cli/progress_bars.py /^ bar_prefix = " "$/;" v class:BlueEmojiBar
bar_prefix venv/lib/python3.10/site-packages/pip/_vendor/progress/bar.py /^ bar_prefix = ' '$/;" v class:ChargingBar
bar_prefix venv/lib/python3.10/site-packages/pip/_vendor/progress/bar.py /^ bar_prefix = ' |'$/;" v class:Bar
bar_suffix venv/lib/python3.10/site-packages/pip/_internal/cli/progress_bars.py /^ bar_suffix = " "$/;" v class:BlueEmojiBar
bar_suffix venv/lib/python3.10/site-packages/pip/_vendor/progress/bar.py /^ bar_suffix = ' '$/;" v class:ChargingBar
bar_suffix venv/lib/python3.10/site-packages/pip/_vendor/progress/bar.py /^ bar_suffix = '| '$/;" v class:Bar
bar_text color.py /^bar_text = white$/;" v
bartlett venv/lib/python3.10/site-packages/numpy/lib/function_base.py /^def bartlett(M):$/;" f
base venv/lib/python3.10/site-packages/numpy/__init__.cython-30.pxd /^ cdef inline PyObject* base(self) nogil:$/;" m class:numpy
base venv/lib/python3.10/site-packages/numpy/core/include/numpy/arrayscalars.h /^ PyObject *base;$/;" m struct:__anona21bb8351808 typeref:typename:PyObject *
@ -17987,6 +17999,7 @@ bitwise_right_shift venv/lib/python3.10/site-packages/numpy/array_api/_elementwi
bitwise_types venv/lib/python3.10/site-packages/numpy/core/tests/test_umath.py /^ bitwise_types = [np.dtype(c) for c in '?' + 'bBhHiIlLqQ' + 'O']$/;" v class:TestBitwiseUFuncs
bitwise_xor venv/lib/python3.10/site-packages/numpy/array_api/_elementwise_functions.py /^def bitwise_xor(x1: Array, x2: Array, \/) -> Array:$/;" f typeref:typename:Array
bitwise_xor venv/lib/python3.10/site-packages/numpy/ma/core.py /^bitwise_xor = _MaskedBinaryOperation(umath.bitwise_xor)$/;" v
black color.py /^black = (0x0, 0x0, 0x0)$/;" v
black venv/lib/python3.10/site-packages/tcod/constants.py /^black = Color(0, 0, 0)$/;" v
black_run venv/lib/python3.10/site-packages/black_primer/lib.py /^async def black_run($/;" f typeref:typename:None
blackman venv/lib/python3.10/site-packages/numpy/lib/function_base.py /^def blackman(M):$/;" f
@ -20877,6 +20890,8 @@ endpoint venv/lib/python3.10/site-packages/numpy/random/tests/test_generator_mt1
endprogs venv/lib/python3.10/site-packages/blib2to3/pgen2/tokenize.py /^endprogs: Final = {$/;" v typeref:typename:Final
endswith venv/lib/python3.10/site-packages/numpy/core/defchararray.py /^ def endswith(self, suffix, start=0, end=None):$/;" m class:chararray
endswith venv/lib/python3.10/site-packages/numpy/core/defchararray.py /^def endswith(a, suffix, start=0, end=None):$/;" f
enemy_atk color.py /^enemy_atk = (0xFF, 0xC0, 0xC0)$/;" v
enemy_die color.py /^enemy_die = (0xFF, 0xA0, 0x30)$/;" v
engine actions.py /^ def engine(self) -> Engine:$/;" m class:Action typeref:typename:Engine
engine components/base_components.py /^ def engine(self) -> Engine:$/;" m class:BaseComponent typeref:typename:Engine
english_capitalize venv/lib/python3.10/site-packages/numpy/core/_string_helpers.py /^def english_capitalize(s):$/;" f
@ -21013,12 +21028,14 @@ eta_td venv/lib/python3.10/site-packages/pip/_vendor/progress/__init__.py /^
etree venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py /^import lxml.etree as etree$/;" I nameref:module:lxml.etree
etree_builders venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py /^from . import etree as etree_builders$/;" x nameref:unknown:etree
ev_ venv/lib/python3.10/site-packages/tcod/event.py /^ def ev_(self, event: Any) -> Optional[T]:$/;" m class:EventDispatch typeref:typename:Optional[T]
ev_keydown input_handlers.py /^ def ev_keydown(self, event: tcod.event.KeyDown) -> None:$/;" m class:HistoryViewer typeref:typename:None
ev_keydown input_handlers.py /^ def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]:$/;" m class:MainGameEventHandler typeref:typename:Optional[Action]
ev_keydown input_handlers.py /^ def ev_keydown(self, event: tcode.event.KeyDown) -> Optional[Action]:$/;" m class:GameOverEventHandler typeref:typename:Optional[Action]
ev_keydown venv/lib/python3.10/site-packages/tcod/event.py /^ def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[T]:$/;" m class:EventDispatch typeref:typename:Optional[T]
ev_keyup venv/lib/python3.10/site-packages/tcod/event.py /^ def ev_keyup(self, event: tcod.event.KeyUp) -> Optional[T]:$/;" m class:EventDispatch typeref:typename:Optional[T]
ev_mousebuttondown venv/lib/python3.10/site-packages/tcod/event.py /^ def ev_mousebuttondown(self, event: tcod.event.MouseButtonDown) -> Optional[T]:$/;" m class:EventDispatch typeref:typename:Optional[T]
ev_mousebuttonup venv/lib/python3.10/site-packages/tcod/event.py /^ def ev_mousebuttonup(self, event: tcod.event.MouseButtonUp) -> Optional[T]:$/;" m class:EventDispatch typeref:typename:Optional[T]
ev_mousemotion input_handlers.py /^ def ev_mousemotion(self, event: tcod.event.MouseMotion) -> None:$/;" m class:EventHandler typeref:typename:None
ev_mousemotion venv/lib/python3.10/site-packages/tcod/event.py /^ def ev_mousemotion(self, event: tcod.event.MouseMotion) -> Optional[T]:$/;" m class:EventDispatch typeref:typename:Optional[T]
ev_mousewheel venv/lib/python3.10/site-packages/tcod/event.py /^ def ev_mousewheel(self, event: tcod.event.MouseWheel) -> Optional[T]:$/;" m class:EventDispatch typeref:typename:Optional[T]
ev_quit input_handlers.py /^ def ev_quit(self, event: tcod.event.Quit) -> Optional[Action]:$/;" m class:EventHandler typeref:typename:Optional[Action]
@ -22107,6 +22124,7 @@ fullTree venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/etr
full_like venv/lib/python3.10/site-packages/numpy/array_api/_creation_functions.py /^def full_like($/;" f typeref:typename:Array
full_like venv/lib/python3.10/site-packages/numpy/core/numeric.py /^def full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None):$/;" f
full_name venv/lib/python3.10/site-packages/setuptools/depends.py /^ def full_name(self):$/;" m class:Require
full_text message_log.py /^ def full_text(self) -> str:$/;" m class:Message typeref:typename:str
full_version venv/lib/python3.10/site-packages/numpy/version.py /^full_version = vinfo['version']$/;" v
func venv/lib/python3.10/site-packages/cffi/_embedding.h /^ void *func; \/* function pointer *\/$/;" m struct:_cffi_pypy_init_s typeref:typename:void *
func venv/lib/python3.10/site-packages/click/_compat.py /^ def func() -> t.TextIO:$/;" f function:_make_cached_stream_func typeref:typename:t.TextIO file:
@ -22866,6 +22884,7 @@ get_name venv/lib/python3.10/site-packages/pip/_internal/commands/configuration.
get_name venv/lib/python3.10/site-packages/setuptools/_distutils/dist.py /^ def get_name(self):$/;" m class:DistributionMetadata
get_names venv/lib/python3.10/site-packages/numpy/lib/recfunctions.py /^def get_names(adtype):$/;" f
get_names venv/lib/python3.10/site-packages/numpy/lib/tests/test_recfunctions.py /^get_names = np.lib.recfunctions.get_names$/;" v
get_names_at_location render_functions.py /^def get_names_at_location(x: int, y: int, game_map: GameMap) -> str:$/;" f typeref:typename:str
get_names_flat venv/lib/python3.10/site-packages/numpy/lib/recfunctions.py /^def get_names_flat(adtype):$/;" f
get_names_flat venv/lib/python3.10/site-packages/numpy/lib/tests/test_recfunctions.py /^get_names_flat = np.lib.recfunctions.get_names_flat$/;" v
get_needs venv/lib/python3.10/site-packages/numpy/f2py/cfuncs.py /^def get_needs():$/;" f
@ -23409,9 +23428,9 @@ handle_PermissionError venv/lib/python3.10/site-packages/black_primer/lib.py /^d
handle_display_options venv/lib/python3.10/site-packages/setuptools/_distutils/dist.py /^ def handle_display_options(self, option_order):$/;" m class:Distribution
handle_display_options venv/lib/python3.10/site-packages/setuptools/dist.py /^ def handle_display_options(self, option_order):$/;" m class:Distribution
handle_enemy_turns engine.py /^ def handle_enemy_turns(self) -> None:$/;" m class:Engine typeref:typename:None
handle_events input_handlers.py /^ def handle_events(self) -> None:$/;" m class:EventHandler typeref:typename:None
handle_events input_handlers.py /^ def handle_events(self) -> None:$/;" m class:GameOverEventHandler typeref:typename:None
handle_events input_handlers.py /^ def handle_events(self) -> None:$/;" m class:MainGameEventHandler typeref:typename:None
handle_events input_handlers.py /^ def handle_events(self, context: tcod.context.Context) -> None:$/;" m class:GameOverEventHandler typeref:typename:None
handle_events input_handlers.py /^ def handle_events(self, context: tcod.context.Context) -> None:$/;" m class:MainGameEventHandler typeref:typename:None
handle_events input_handlers.py /^ def handle_events(self, context: tcode.context.Context) -> None:$/;" m class:EventHandler typeref:typename:None
handle_extra_path venv/lib/python3.10/site-packages/setuptools/_distutils/command/install.py /^ def handle_extra_path(self):$/;" m class:install
handle_extra_path venv/lib/python3.10/site-packages/setuptools/command/install.py /^ def handle_extra_path(self):$/;" m class:install
handle_line venv/lib/python3.10/site-packages/pip/_internal/req/req_file.py /^def handle_line($/;" f typeref:typename:Optional[ParsedRequirement]
@ -27315,6 +27334,8 @@ old_urlopen venv/lib/python3.10/site-packages/numpy/lib/tests/test__datasource.p
oldnumeric venv/lib/python3.10/site-packages/numpy/__init__.py /^ oldnumeric = 'removed'$/;" v
omit_optional_tags venv/lib/python3.10/site-packages/pip/_vendor/html5lib/serializer.py /^ omit_optional_tags = True$/;" v class:HTMLSerializer
on_powerpc venv/lib/python3.10/site-packages/numpy/core/tests/test_umath.py /^def on_powerpc():$/;" f
on_render input_handlers.py /^ def on_render(self, console: tcod.Console) -> None:$/;" m class:EventHandler typeref:typename:None
on_render input_handlers.py /^ def on_render(self, console: tcod.Console)-> None:$/;" m class:HistoryViewer typeref:typename:None
one venv/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/more.py /^def one(iterable, too_short=None, too_long=None):$/;" f
oneOf venv/lib/python3.10/site-packages/pip/_vendor/pyparsing.py /^def oneOf(strs, caseless=False, useRegex=True, asKeyword=False):$/;" f
oneOf venv/lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing.py /^def oneOf( strs, caseless=False, useRegex=True ):$/;" f
@ -28171,7 +28192,7 @@ pkg_name venv/lib/python3.10/site-packages/numpy/distutils/npy_pkg_config.py /^
pkg_resources_distribution_for_wheel venv/lib/python3.10/site-packages/pip/_internal/utils/wheel.py /^def pkg_resources_distribution_for_wheel(wheel_zip, name, location):$/;" f
pkg_to_filename venv/lib/python3.10/site-packages/numpy/distutils/npy_pkg_config.py /^def pkg_to_filename(pkg_name):$/;" f
pkgname venv/lib/python3.10/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini /^pkgname=numpy.core$/;" k section:variables
place entity.py /^ def place(self, x: int, y: int, gamemap: Optional[GameMap] = None) -> None:$/;" m class:Entity typeref:typename:None
place entity.py /^ def place(self, x: int, y: int, game_map: Optional[GameMap] = None) -> None:$/;" m class:Entity typeref:typename:None
place venv/lib/python3.10/site-packages/numpy/lib/function_base.py /^def place(arr, mask, vals):$/;" f
place_entities procgen.py /^def place_entities($/;" f typeref:typename:None
plainrep venv/lib/python3.10/site-packages/numpy/distutils/conv_template.py /^plainrep = re.compile(r"([^*]+)\\*(\\d+)")$/;" v
@ -28188,6 +28209,8 @@ platform_tags venv/lib/python3.10/site-packages/pip/_vendor/packaging/_manylinux
platform_tags venv/lib/python3.10/site-packages/pip/_vendor/packaging/_musllinux.py /^def platform_tags(arch: str) -> Iterator[str]:$/;" f typeref:typename:Iterator[str]
platforms venv/lib/python3.10/site-packages/pip/_internal/cli/cmdoptions.py /^platforms: Callable[..., Option] = partial($/;" v typeref:typename:Callable[..., Option]
player entity_factories.py /^player = Actor($/;" v
player_atk color.py /^player_atk = (0xE0, 0xE0, 0xE0)$/;" v
player_die color.py /^player_die = (0xFF, 0x30, 0x30)$/;" v
plugin venv/lib/python3.10/site-packages/numpy/typing/mypy_plugin.py /^ def plugin(version: str) -> type[_NumpyPlugin]:$/;" f typeref:typename:type[_NumpyPlugin]
plugins venv/lib/python3.10/site-packages/numpy/typing/tests/data/mypy.ini /^plugins = numpy.typing.mypy_plugin$/;" k section:mypy
poetry venv/lib/python3.10/site-packages/black_primer/primer.json /^ "poetry": {$/;" o object:projects
@ -29075,12 +29098,16 @@ remove_tree venv/lib/python3.10/site-packages/setuptools/_distutils/dir_util.py
removespaces venv/lib/python3.10/site-packages/numpy/f2py/crackfortran.py /^def removespaces(expr):$/;" f
rename_fields venv/lib/python3.10/site-packages/numpy/lib/recfunctions.py /^def rename_fields(base, namemapper):$/;" f
renames venv/lib/python3.10/site-packages/pip/_internal/utils/misc.py /^def renames(old, new):$/;" f
render engine.py /^ def render(self, console: Console, context: Context) -> None:$/;" m class:Engine typeref:typename:None
render engine.py /^ def render(self, console: Console) -> None:$/;" m class:Engine typeref:typename:None
render game_map.py /^ def render(self, console: Console) -> None:$/;" m class:GameMap typeref:typename:None
render message_log.py /^ def render($/;" m class:MessageLog typeref:typename:None
render venv/lib/python3.10/site-packages/pip/_vendor/html5lib/serializer.py /^ def render(self, treewalker, encoding=None):$/;" m class:HTMLSerializer
render venv/lib/python3.10/site-packages/tcod/tileset.py /^ def render(self, console: tcod.console.Console) -> NDArray[np.uint8]:$/;" m class:Tileset typeref:typename:NDArray[np.uint8]
render_bar render_functions.py /^def render_bar($/;" f typeref:typename:None
render_finish venv/lib/python3.10/site-packages/click/_termui_impl.py /^ def render_finish(self) -> None:$/;" m class:ProgressBar typeref:typename:None
render_headers venv/lib/python3.10/site-packages/pip/_vendor/urllib3/fields.py /^ def render_headers(self):$/;" m class:RequestField
render_messages message_log.py /^ def render_messages($/;" m class:MessageLog typeref:typename:None
render_names_at_mouse_location render_functions.py /^def render_names_at_mouse_location($/;" f typeref:typename:None
render_progress venv/lib/python3.10/site-packages/click/_termui_impl.py /^ def render_progress(self) -> None:$/;" m class:ProgressBar typeref:typename:None
renderer_type venv/lib/python3.10/site-packages/tcod/context.py /^ def renderer_type(self) -> int:$/;" m class:Context typeref:typename:int
repack_fields venv/lib/python3.10/site-packages/numpy/lib/recfunctions.py /^def repack_fields(a, align=False, recurse=False):$/;" f
@ -29617,6 +29644,14 @@ runtime_library_dir_option venv/lib/python3.10/site-packages/setuptools/_distuti
s venv/lib/python3.10/site-packages/numpy/doc/constants.py /^ s = "\\n".join(new_lines)$/;" v
s venv/lib/python3.10/site-packages/numpy/doc/constants.py /^ s = textwrap.dedent(doc).replace("\\n", "\\n ")$/;" v
s venv/lib/python3.10/site-packages/tcod/event.py /^ s = 115$/;" v class:KeySym
s:l Session.vim /^let s:l = 8 - ((7 * winheight(0) + 28) \/ 56)$/;" v
s:save_splitbelow Session.vim /^let s:save_splitbelow = &splitbelow$/;" v
s:save_splitright Session.vim /^let s:save_splitright = &splitright$/;" v
s:save_winminheight Session.vim /^let s:save_winminheight = &winminheight$/;" v
s:save_winminwidth Session.vim /^let s:save_winminwidth = &winminwidth$/;" v
s:so_save Session.vim /^let s:so_save = &g:so | let s:siso_save = &g:siso | setg so=0 siso=0 | setl so=-1 siso=-1$/;" v
s:sx Session.vim /^let s:sx = expand("<sfile>:p:r")."x.vim"$/;" v
s:wipebuf Session.vim /^ let s:wipebuf = bufnr('%')$/;" v
sNAN venv/lib/python3.10/site-packages/numpy/core/tests/data/generate_umath_validation_data.cpp /^#define sNAN /;" d file:
s_ venv/lib/python3.10/site-packages/numpy/lib/index_tricks.py /^s_ = IndexExpression(maketuple=False)$/;" v
s_binomial_t venv/lib/python3.10/site-packages/numpy/core/include/numpy/random/distributions.h /^typedef struct s_binomial_t {$/;" s
@ -30544,7 +30579,7 @@ space_before_trailing_solidus venv/lib/python3.10/site-packages/pip/_vendor/html
space_re venv/lib/python3.10/site-packages/numpy/core/_internal.py /^space_re = re.compile(r'\\s+$')$/;" v
spacesAngleBrackets venv/lib/python3.10/site-packages/pip/_vendor/html5lib/_inputstream.py /^spacesAngleBrackets = spaceCharactersBytes | frozenset([b">", b"<"])$/;" v
sparse_dtype venv/lib/python3.10/site-packages/numpy/core/tests/test_dtype.py /^ sparse_dtype = np.dtype([('a', {'names':['ab'], 'formats':['f'],$/;" v class:TestStructuredDtypeSparseFields
spawn entity.py /^ def spawn(self: T, gamemap: GameMap, x: int, y: int) -> T:$/;" m class:Entity typeref:typename:T
spawn entity.py /^ def spawn(self: T, game_map: GameMap, x: int, y: int) -> T:$/;" m class:Entity typeref:typename:T
spawn venv/lib/python3.10/site-packages/setuptools/_distutils/_msvccompiler.py /^ def spawn(self, cmd):$/;" m class:MSVCCompiler
spawn venv/lib/python3.10/site-packages/setuptools/_distutils/ccompiler.py /^ def spawn(self, cmd, **kwargs):$/;" m class:CCompiler
spawn venv/lib/python3.10/site-packages/setuptools/_distutils/cmd.py /^ def spawn(self, cmd, search_path=1, level=1):$/;" m class:Command
@ -38512,6 +38547,7 @@ was_installed_by_pip venv/lib/python3.10/site-packages/pip/_internal/self_outdat
wchar_const venv/lib/python3.10/site-packages/pycparser/c_lexer.py /^ wchar_const = 'L'+char_const$/;" v class:CLexer
weakreflist venv/lib/python3.10/site-packages/numpy/core/include/numpy/ndarraytypes.h /^ PyObject *weakreflist;$/;" m struct:tagPyArrayObject_fields typeref:typename:PyObject *
weights venv/lib/python3.10/site-packages/numpy/lib/tests/test_function_base.py /^ weights = np.array([1.0, 4.0, 1.0])$/;" v class:TestCov
welcome_text color.py /^welcome_text = (0x20, 0xA0, 0xFF)$/;" v
wheel_dist_info_dir venv/lib/python3.10/site-packages/pip/_internal/utils/wheel.py /^def wheel_dist_info_dir(source, name):$/;" f
wheel_file_re venv/lib/python3.10/site-packages/pip/_internal/models/wheel.py /^ wheel_file_re = re.compile($/;" v class:Wheel
wheel_metadata venv/lib/python3.10/site-packages/pip/_internal/utils/wheel.py /^def wheel_metadata(source, dist_info_dir):$/;" f
@ -38525,6 +38561,7 @@ where venv/lib/python3.10/site-packages/numpy/ma/core.py /^def where(condition,
where venv/lib/python3.10/site-packages/pip/_vendor/certifi/core.py /^ def where():$/;" f
where venv/lib/python3.10/site-packages/pip/_vendor/certifi/core.py /^ def where():$/;" f
which venv/lib/python3.10/site-packages/pip/_vendor/distlib/compat.py /^ def which(cmd, mode=os.F_OK | os.X_OK, path=None):$/;" f
white color.py /^white = (0xFF, 0xFF, 0xFF)$/;" v
white venv/lib/python3.10/site-packages/tcod/constants.py /^white = Color(255, 255, 255)$/;" v
whiteStrs venv/lib/python3.10/site-packages/pip/_vendor/pyparsing.py /^ whiteStrs = {$/;" v class:White
whiteStrs venv/lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing.py /^ whiteStrs = {$/;" v class:White