GF2QFPRRD67Y6EORPB2YU5VVX6VGMOJQDGGZGO6BKBWBIKRRQ6UAC <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>ANSIBlackColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC4xMTc2NDcwNTg4IDAuMTI5NDExNzY0NyAwLjE1Mjk0MTE3NjUAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>ANSIBlueColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAmMC4zODAzOTIxNTY5IDAuNjg2Mjc0NTA5OCAwLjkzNzI1NDkwMgAQAYAC0hQVFhdaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohYYWE5TT2JqZWN0CBEaJCkyN0lMUVNXXWRqd36nqauwu8TMzwAAAAAAAAEBAAAAAAAAABkAAAAAAAAAAAAAAAAAAADY</data><key>ANSIBrightBlackColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC4zNjA3ODQzMTM3IDAuMzg4MjM1Mjk0MSAwLjQzOTIxNTY4NjMAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>ANSIBrightBlueColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAmMC4zODAzOTIxNTY5IDAuNjg2Mjc0NTA5OCAwLjkzNzI1NDkwMgAQAYAC0hQVFhdaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohYYWE5TT2JqZWN0CBEaJCkyN0lMUVNXXWRqd36nqauwu8TMzwAAAAAAAAEBAAAAAAAAABkAAAAAAAAAAAAAAAAAAADY</data><key>ANSIBrightCyanColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAmMC4zMzcyNTQ5MDIgMC43MTM3MjU0OTAyIDAuNzYwNzg0MzEzNwAQAYAC0hQVFhdaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohYYWE5TT2JqZWN0CBEaJCkyN0lMUVNXXWRqd36nqauwu8TMzwAAAAAAAAEBAAAAAAAAABkAAAAAAAAAAAAAAAAAAADY</data><key>ANSIBrightGreenColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC41OTYwNzg0MzE0IDAuNzY0NzA1ODgyNCAwLjQ3NDUwOTgwMzkAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>ANSIBrightMagentaColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC43NzY0NzA1ODgyIDAuNDcwNTg4MjM1MyAwLjg2NjY2NjY2NjcAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>ANSIBrightRedColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC44Nzg0MzEzNzI1IDAuNDIzNTI5NDExOCAwLjQ1ODgyMzUyOTQAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>ANSIBrightWhiteColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAaMSAwLjk5OTk3NDM3IDAuOTk5OTkxMjk3NwAQAYAC0hQVFhdaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohYYWE5TT2JqZWN0CBEaJCkyN0lMUVNXXWRqd36bnZ+kr7jAwwAAAAAAAAEBAAAAAAAAABkAAAAAAAAAAAAAAAAAAADM</data><key>ANSIBrightYellowColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAeMC44MTk2MDc4NDMxIDAuNjAzOTIxNTY4NiAwLjQAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+n6GjqLO8xMcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA0A==</data><key>ANSICyanColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAmMC4zMzcyNTQ5MDIgMC43MTM3MjU0OTAyIDAuNzYwNzg0MzEzNwAQAYAC0hQVFhdaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohYYWE5TT2JqZWN0CBEaJCkyN0lMUVNXXWRqd36nqauwu8TMzwAAAAAAAAEBAAAAAAAAABkAAAAAAAAAAAAAAAAAAADY</data><key>ANSIGreenColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC41OTYwNzg0MzE0IDAuNzY0NzA1ODgyNCAwLjQ3NDUwOTgwMzkAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>ANSIMagentaColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC43NzY0NzA1ODgyIDAuNDcwNTg4MjM1MyAwLjg2NjY2NjY2NjcAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>ANSIRedColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC44Nzg0MzEzNzI1IDAuNDIzNTI5NDExOCAwLjQ1ODgyMzUyOTQAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>ANSIWhiteColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC42NzA1ODgyMzUzIDAuNjk4MDM5MjE1NyAwLjc0OTAxOTYwNzgAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>ANSIYellowColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAeMC44MTk2MDc4NDMxIDAuNjAzOTIxNTY4NiAwLjQAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+n6GjqLO8xMcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA0A==</data><key>BackgroundAlphaInactive</key><real>0.80306177745664742</real><key>BackgroundBlur</key><real>0.0</real><key>BackgroundBlurInactive</key><real>0.0</real><key>BackgroundColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC4xMTc2NDcwNTg4IDAuMTI5NDExNzY0NyAwLjE1Mjk0MTE3NjUAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>BackgroundSettingsForInactiveWindows</key><true/><key>BlinkText</key><false/><key>CursorColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC4zNjA3ODQzMTM3IDAuMzg4MjM1Mjk0MSAwLjQzOTIxNTY4NjMAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>CursorType</key><integer>0</integer><key>DisableANSIColor</key><false/><key>Font</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGkCwwVFlUkbnVsbNQNDg8QERITFFZOU1NpemVYTlNmRmxhZ3NWTlNOYW1lViRjbGFzcyNALAAAAAAAABAQgAKAA18QEEZpcmFDb2RlLVJlZ3VsYXLSFxgZGlokY2xhc3NuYW1lWCRjbGFzc2VzVk5TRm9udKIZG1hOU09iamVjdAgRGiQpMjdJTFFTWF5nbnd+hY6QkpSnrLfAx8oAAAAAAAABAQAAAAAAAAAcAAAAAAAAAAAAAAAAAAAA0w==</data><key>FontAntialias</key><true/><key>FontHeightSpacing</key><integer>1</integer><key>FontWidthSpacing</key><integer>1</integer><key>ProfileCurrentVersion</key><real>2.0699999999999998</real><key>RestoreLines</key><integer>3600</integer><key>ScrollAlternateScreen</key><false/><key>ScrollbackLines</key><integer>3600</integer><key>SelectionColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC4yMjc0NTA5ODA0IDAuMjQ3MDU4ODIzNSAwLjI5NDExNzY0NzEAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>ShouldLimitScrollback</key><integer>1</integer><key>ShowActiveProcessArgumentsInTabTitle</key><false/><key>ShowActiveProcessArgumentsInTitle</key><false/><key>ShowActiveProcessInTitle</key><false/><key>ShowDimensionsInTitle</key><true/><key>ShowRepresentedURLInTitle</key><true/><key>ShowRepresentedURLPathInTitle</key><false/><key>ShowShellCommandInTitle</key><false/><key>ShowTTYNameInTitle</key><false/><key>ShowWindowSettingsNameInTitle</key><false/><key>TerminalType</key><string>ansi</string><key>TextBoldColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC42NzA1ODgyMzUzIDAuNjk4MDM5MjE1NyAwLjc0OTAxOTYwNzgAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>TextColor</key><data>YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxARElVOU1JHQlxOU0NvbG9yU3BhY2VWJGNsYXNzTxAnMC42NzA1ODgyMzUzIDAuNjk4MDM5MjE1NyAwLjc0OTAxOTYwNzgAEAGAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIWGFhOU09iamVjdAgRGiQpMjdJTFFTV11kand+qKqssbzFzdAAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==</data><key>UseBoldFonts</key><false/><key>UseBrightBold</key><false/><key>VisualBell</key><true/><key>WindowTitle</key><string></string><key>blackColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmg7JNIT2DkvUjPoO+F0s+AYY=</data><key>blueColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmgyqcAj6DtOHsPoO+RUg/AYY=</data><key>brightBlackColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmg+ZzgjyDs44BPoNahyM+AYY=</data><key>brightBlueColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmg7yT4T6DEXcCP4POUAQ/AYY=</data><key>brightCyanColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmg7CIAT+Dj5oQP4N8ShA/AYY=</data><key>brightGreenColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmgzyujT6DFZy2PoOYFsQ+AYY=</data><key>brightMagentaColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmgxMjsj6D+uazPoNkyTc/AYY=</data><key>brightRedColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmgyfkPT+D/15aPoMgl5Y9AYY=</data><key>brightWhiteColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmg49LfT+D0Dt1P4MGM10/AYY=</data><key>brightYellowColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmg1MTpj6DeHnQPoPQg+A+AYY=</data><key>columnCount</key><integer>120</integer><key>cyanColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmg4VRFj6DfyESP4PkZwY/AYY=</data><key>greenColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmg9lI5j6DIYkKP4PVjKU8AYY=</data><key>keyMapBoundKeys</key><dict><key>#F739</key><string>toggleNumLock:</string><key>$F702</key><string>[1;2D</string><key>$F703</key><string>[1;2C</string><key>$F708</key><string>[25~</string><key>$F709</key><string>[26~</string><key>$F70A</key><string>[28~</string><key>$F70B</key><string>[29~</string><key>$F70C</key><string>[31~</string><key>$F70D</key><string>[32~</string><key>$F70E</key><string>[33~</string><key>$F70F</key><string>[34~</string><key>$F728</key><string>[3;2~</string><key>F704</key><string>OP</string><key>F705</key><string>OQ</string><key>F706</key><string>OR</string><key>F707</key><string>OS</string><key>F708</key><string>[15~</string><key>F709</key><string>[17~</string><key>F70A</key><string>[18~</string><key>F70B</key><string>[19~</string><key>F70C</key><string>[20~</string><key>F70D</key><string>[21~</string><key>F70E</key><string>[23~</string><key>F70F</key><string>[24~</string><key>F710</key><string>[25~</string><key>F711</key><string>[26~</string><key>F712</key><string>[28~</string><key>F713</key><string>[29~</string><key>F714</key><string>[31~</string><key>F715</key><string>[32~</string><key>F716</key><string>[33~</string><key>F717</key><string>[34~</string><key>F728</key><string>[3~</string><key>F729</key><string></string><key>F72B</key><string></string><key>F72C</key><string></string><key>F72D</key><string></string><key>^F702</key><string>[1;5D</string><key>^F703</key><string>[1;5C</string><key>^F728</key><string>[3;5~</string><key>~F702</key><string>b</string><key>~F703</key><string>f</string><key>~F704</key><string>[17~</string><key>~F705</key><string>[18~</string><key>~F706</key><string>[19~</string><key>~F707</key><string>[20~</string><key>~F708</key><string>[21~</string><key>~F709</key><string>[23~</string><key>~F70A</key><string>[24~</string><key>~F70B</key><string>[25~</string><key>~F70C</key><string>[26~</string><key>~F70D</key><string>[28~</string><key>~F70E</key><string>[29~</string><key>~F70F</key><string>[31~</string><key>~F710</key><string>[32~</string><key>~F711</key><string>[33~</string><key>~F712</key><string>[34~</string><key>~^F728</key><string>[3;5~</string></dict><key>magentaColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmg/4CRz+DBTzdPYMgzt4+AYY=</data><key>name</key><string>One Dark</string><key>redColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmg6i7UT+DUATePYMl2hA+AYY=</data><key>rowCount</key><integer>36</integer><key>type</key><string>Window Settings</string><key>useOptionAsMetaKey</key><true/><key>whiteColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmgzqGaj+D2tdjP4NYPUw/AYY=</data><key>yellowColour</key><data>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmg0DAJT+DB17vPoM4Y8A8AYY=</data></dict></plist>
#! /usr/bin/env fish# Wrapper that invokes the AWS CLI with cached credentials provided by imaws.# Helps Lens, et al function better with imaws & role assumption.# TODO: deal with assuming special roles (other than the profile default)# - how? where does AWS_PROFILE even come from when this script gets invoked?if test -n "$AWS_ACCESS_KEY_ID"; and test -n "$AWS_SECRET_ACCESS_KEY"# Nothing to do; we already (appear to) have valid credsaws $argvexit 0endset -l min_ttl 60set -l profile_name $AWS_PROFILEset mfa_serial (grep -A5 "\[profile $profile_name\]" ~/.aws/config | grep mfa_serial | awk 'BEGIN { FS = " ?= ?" } ; { print $2 }')set role_arn (grep -A5 "\[profile $profile_name\]" ~/.aws/config | grep role_arn | awk 'BEGIN { FS = " ?= ?" } ; { print $2 }')set source_profile (grep -A5 "\[profile $profile_name\]" ~/.aws/config | grep source_profile | awk 'BEGIN { FS = " ?= ?" } ; { print $2 }')if test -z "$role_arn"echo "imaws-wrapper: No profile '$profile_name' in ~/.aws/config"exit 1endset -l role_account_id (echo $role_arn | cut -d: -f5)set -l cache_key (echo $role_arn | cut -d: -f5)-(echo $role_arn | cut -d/ -f2)set -l json_file $HOME/.aws/cli/cache/imaws-$cache_key.jsonif test -f "$json_file"set -gx AWS_SESSION_EXPIRY (jq -r '.Credentials.Expiration | strptime("%Y-%m-%dT%H:%M:%S+00:00") | mktime' $json_file)if test (math $AWS_SESSION_EXPIRY - (jq -n 'now|floor')) -gt $min_ttlset -gx AWS_ACCOUNT_ID $role_account_idset -gx AWS_PROFILE $profile_nameset -gx AWS_ACCESS_KEY_ID (jq -r .Credentials.AccessKeyId $json_file)set -gx AWS_SECRET_ACCESS_KEY (jq -r .Credentials.SecretAccessKey $json_file)set -gx AWS_SESSION_TOKEN (jq -r .Credentials.SessionToken $json_file)aws $argvexit 0endendecho "imaws-wrapper: Credentials expired; please run imaws to refresh them"exit 1
# Run a project-local Ruby/JavaScript executable in the PWD.function xif test -f Gemfile; or test (count *.gemspec) -gt 0bundle exec $argvelse if test -f package.jsonset -l pmgr (cat package.json | jq -r .packageManager)switch $pmgrcase 'npm*'npx $argvcase 'yarn*'yarn exec $argvcase '*'if test -f package-lock.jsonnpx $argvelse if test -f yarn.lockyarn $argvelseecho "i: Dunno how to run; please add packageManager to package.json"return 1endendendend
# CURRENTLY: watch dir for changes and then invoke a command (in a loop)function watchwhile trueeval $argv[2..-1]set -l output (fswatch -L -r -t -1 $argv[1])if test -z "$output"break # user hit Ctrl+Celseclear # filesystem changedendendend# FORMERLY: watch a container's logs across restarts# function watch# set -l subject $argv[1]# if test -f docker-compose.yml# while true# docker-compose logs -f $subject# if test $status -ne 0# break# end# echo "Recommence watching in 10 seconds..."# sleep 10# end# else if test -d $subject# echo "TODO: watching dirs is not implemented"# else# echo "watch: $subject is neither a directory nor a docker-compose service"# end# end
# unset all environment variables matching a patternfunction unsetset -l all (env | grep -E $argv[1] | cut -d= -f1)echo "unset: $all"for e in $allset -e $eendend
function trackset -l branch (git symbolic-ref HEAD 2>/dev/null | sed -e 's:refs/heads/::')git branch --set-upstream-to $argv[1]/$branchend
# Run a script/task of a Ruby or Javascript project located in PWD.function rif test -f Makefile; and grep -q "$argv[1]:" Makefilemake $argvelse if test -f Rakefilebundle exec rake $argvelse if test -f package.jsonset -l pmgr (cat package.json | jq -r .packageManager)switch $pmgrcase 'yarn*'yarn $argvcase '*'npm run $argvendelseecho "r: Nothing seems to be runnable in this folder"endend
# Push the working branch to its remote tracking branch at origin. If# there is no remote tracking branch, then push to an upstream branch of the# same name and set upstream for future pushes.function pushset -l branch (git symbolic-ref HEAD 2>/dev/null | sed -e 's:refs/heads/::')set -l tracking_branch (git rev-parse --abbrev-ref --symbolic-full-name '@{upstream}' 2>/dev/null)or set -e tracking_branchif test -n "$tracking_branch"git pushelsegit push --set-upstream origin $branchendend
# Pull from remote. Performs a `git fetch` and fast-forwards the local branch# named in $argv[1] (or the working branch, if no argument is passed).## Usage:# `pull` to fast-forward working branch# `pull branchname` to fast-forward chosen branchfunction pullset -l working_branch (git symbolic-ref HEAD 2>/dev/null | sed -e 's:refs/heads/::')test -n "$argv[1]"; and set -l branch $argv[1]; or set -l branch $working_branchgit pull -p --ff-only origin $branchend
# Pull All the Things! Performs a `git fetch`, fast-forwards the working branch# if applicable, and pulls the Docker image of the corresponding tag name,# if any.## Does not give any output from `git pull`; this would be nice to have...## Usage:# `pull!` to fast-forward working branch and pull corresponding image# `pull! branchname` to fast-forward chosen branch and pull corresponding imagefunction pull!# Git repository parametersset -l working_branch (git symbolic-ref HEAD 2>/dev/null | sed -e 's:refs/heads/::')test -n "$argv[1]"; and set -l branch $argv[1]; or set -l branch $working_branch# Docker image parameters (derived from Git parameters)set -l org (basename (dirname $PWD))set -l repository (basename $PWD)set -l tag $branch# special case for master -> latest naming conventionif test $tag = masterset tag latestendset -l image "$org/$repository:$tag"echo "Pulling branch: origin/$branch"git pull --ff-only origin $branch &if test -f Dockerfileecho "Pulling image: $image"docker pull $imageelseecho "No Dockerfile; skip image pull"endjobs | grep -q 'git pull'; and fg %gitend
# Delete all local branches that are fully merged into master.function pruneargparse --name=prune 'r/remote' -- $argvor returnif test -n "$_flag_r"echo "Prune remote branches (WARNING: only understands true merge):"git remote prune origingit branch -r --merged=origin/master | grep -vE 'master|\*' | xargs -L 1 echoread -P "Remove ALL of the above branches (please respond 'yes')? " confirmationif test "$confirmation" = "yes"git branch -r --merged=origin/master | grep -vE 'master|\*' | sed -e 's/^ *origin\//:/' | xargs git push originendelsegit remote prune originecho "Pruning local repository"for branchname in (git branch -l --format='%(refname:short)')if ! string match -r '^\\*' $branchnameif test -z (git branch -lr origin/$branchname)echo -n ' * 'git branch -D $branchnameendendendendend
# Open a browser to GitHub in order to compare this branch and/or open a# pull request to another branch.function prset -l remote (git remote -v | grep push | head -1 | sed 's|^.*github.com[:/]\(.*\)\.git.*$|\1|')set -l source (git symbolic-ref HEAD 2>/dev/null | sed -e 's:refs/heads/::')set -l dest $argv[1]if test -n "$dest"if [ $dest = master ]; and git show-ref -q --heads mainecho "Using main (not $dest) as default branch -- you insensitive prick!"set dest mainendopen "https://github.com/$remote/pull/new/$dest...$source"elseopen "https://github.com/$remote/compare/$source"endend
# Process a PDF with OCR to add a searchable text layerfunction ocrdocker run -it --rm -v (pwd):/~ petpaulsen/ocr $argvend
# AWS assume-role with fish sauce and an IM garnish.function impushargparse --name=impush 'h/help' -- $argv 2> /dev/nullor set _flag_h 1if test -n "$_flag_h"echo "Usage: impush"echo "TODO.."return 1endpushd ~/Code/appfolio/imcd backend/api/deployset release_name (git symbolic-ref --short HEAD | sed 's/\([A-Z]\)/-\1/g;s/^-//' | tr '[:upper:]' '[:lower:]')bin/coreapi release delete $release_namebin/coreapi release create $release_name --sha=(HEAD)cd ../../../deployset account_name $release_namebin/im account create $account_name --rel=$release_namepopdend
function imchamber__pwd --on-variable=PWDif test -f .chamberrcimchamberendend
function imchamberargparse --name=imchamber 'f/force' 'h/help' -- $argv 2> /dev/nullor set _flag_h 1set -l argcount (count $argv)set -l fingerprint ""set -l services ""if test $argcount -eq 0set -l gci_account_id ''set -l gci_arn (aws sts get-caller-identity --output=text --query=Arn 2> /dev/null)if string match -q '*:assumed-role/*' $gci_arnset gci_account_id (echo $gci_arn | cut -d: -f5)elseecho "imchamber: skipping (no AWS credentials available); use --force to override"return 0endset -l rcfile .chamberrcif test -f .chamberrc.$gci_account_idset rcfile ".chamberrc.$gci_account_id"endif test -f $rcfileset fingerprint "$gci_account_id"-(md5 -q $rcfile)set services (cat $rcfile)endelse if test $argcount -gt 0for service in $argvset -a services "env $service"endendecho "5"if test -n "$_flag_h"; or test -z "$services"echo "Usage: imchamber <service> [service2 ...]"echo " - or, write .chamberrc to PWD containing `chamber` commands, one per line"echo ""echo "Exports secrets from the designated chamber service(s) to your shell environment."echo ""echo "Example .chamberrc file:"echo " env service1"echo " env service2"echo ""echo "Flags:"echo " force - re-run chamberrc even if already run"return 1endif test -n "$fingerprint"; and test "$fingerprint" = "$__imchamber_last_fingerprint"; and test -z "$_flag_f"echo "imchamber: skipping (already ran successfully); use --force to override"return 0endset -l num (count $services)echo "imchamber: automating $num commands"for cmd in $servicesif not string match -qr '^\s*#|^$' $cmd # ignore comments and empty linesecho "+ $cmd"if string match -qr '^env' $cmdset -l cmd_suffix (string sub -s5 $cmd)set -l secrets_json (chamber export --format=json $cmd_suffix)if test $status -ne 0echo "imchamber: error exporting secrets from $cmd_suffix"return 1endset -l secrets_names (echo $secrets_json | jq -r 'keys | .[]')for name in $secrets_namesset -gx (echo $name | tr a-z A-Z) (echo $secrets_json | jq -r .$name)endelseset -l entire_cmd "chamber $cmd"eval $entire_cmdendendendif test -n "$fingerprint"set -g __imchamber_last_fingerprint $fingerprintendend
# AWS assume-role with fish sauce and an IM garnish.function imawsargparse --name=imaws 'h/help' 'c/cached' 't/ttl' 'u/unset' -- $argv 2> /dev/nullor set _flag_h 1set -l profile_name $argv[1]set -l role_name $argv[2]if test -n "$_flag_h"echo "Usage: imaws [--cached] [--ttl=<ttl>] <arn|profile>"echo " Uses the AWS CLI to assume-role (w/ MFA if required) into an AWS profile"echo " as named in your from ~/.aws/config file, or as specified by an IAM role ARN."echo "Flags:"echo " -c / --cached - do not obtain fresh credentials; exit silently if none cached"echo " -t / --ttl - min acceptable TTL for cached credentials (default 3600 sec)"echo ""echo "To unset all environment variables and restore AWS CLI to its default behavior,"echo "run imaws without an ARN or profile name."return 1endset -ge AWS_ACCOUNT_IDset -ge AWS_PROFILEset -ge AWS_ACCESS_KEY_IDset -ge AWS_SECRET_ACCESS_KEYset -ge AWS_SESSION_EXPIRYset -ge AWS_SESSION_TOKENset -ge IM_AWS_ACCESS_KEYset -ge IM_AWS_SESSION_TOKENset -ge IM_AWS_SECRET_ACCESS_KEYif test -z "$argv[1]"; or test -n "$_flag_u"echo "imaws: unsetting all environment variables"echo "(For usage information, run imaws --help)"return 0endif test -n "$_flag_t"set min_ttl $_flag_telseset min_ttl 3600endset -l role_arn ''set -l mfa_serial ''set -l profile_name ''if string match -qr '^arn:' $argv[1]set role_arn $argv[1]if test -n "$AWS_MFA_SERIAL"set mfa_serial $AWS_MFA_SERIALendelseset profile_name $argv[1]set mfa_serial (grep -A5 "\[profile $profile_name\]" ~/.aws/config | grep mfa_serial | awk 'BEGIN { FS = " ?= ?" } ; { print $2 }')set role_arn (grep -A5 "\[profile $profile_name\]" ~/.aws/config | grep role_arn | awk 'BEGIN { FS = " ?= ?" } ; { print $2 }')set source_profile (grep -A5 "\[profile $profile_name\]" ~/.aws/config | grep source_profile | awk 'BEGIN { FS = " ?= ?" } ; { print $2 }')if test -z "$role_arn"echo "imaws: No profile '$profile_name' in ~/.aws/config"return 1endif test -n "$role_name"set role_arn (echo $role_arn | sed "s/:role\/.*/:role\/$role_name/")echo "imaws: Specifically assuming the $role_name role ($role_arn)"endendset -l role_account_id (echo $role_arn | cut -d: -f5)set -l cache_key (echo $role_arn | cut -d: -f5)-(echo $role_arn | cut -d/ -f2)set -l json_file $HOME/.aws/cli/cache/imaws-$cache_key.jsonset -l login_account_alias "unknown"if test -f "$json_file"set -gx AWS_SESSION_EXPIRY (jq -r '.Credentials.Expiration | strptime("%Y-%m-%dT%H:%M:%S+00:00") | mktime' $json_file)if test (math $AWS_SESSION_EXPIRY - (jq -n 'now|floor')) -gt $min_ttl# NB: Sets creds globally (and weirdly, not locally) for future shell commandsset -gx AWS_ACCOUNT_ID $role_account_idset -gx AWS_PROFILE $profile_nameset -gx AWS_ACCESS_KEY_ID (jq -r .Credentials.AccessKeyId $json_file)set -gx AWS_SECRET_ACCESS_KEY (jq -r .Credentials.SecretAccessKey $json_file)set -gx AWS_SESSION_TOKEN (jq -r .Credentials.SessionToken $json_file)# Deal with shitty old E2E suites that need CircleCI-style env vars (yech!)set -gx IM_AWS_ACCESS_KEY $AWS_ACCESS_KEY_IDset -gx IM_AWS_SECRET_ACCESS_KEY $AWS_SECRET_ACCESS_KEYset -gx IM_AWS_SESSION_TOKEN $AWS_SESSION_TOKENecho "imaws: Resumed CLI session for $role_arn"if test -f .chamberrc# Set creds locally so instaneous imchamber invocation can use them.# The `-gx` above can't be seen within the subroutine, weirdly enough. Maybe a fish bug?set -lx AWS_ACCOUNT_ID $role_account_idset -lx AWS_PROFILE $profile_nameset -lx AWS_ACCESS_KEY_ID (jq -r .Credentials.AccessKeyId $json_file)set -lx AWS_SECRET_ACCESS_KEY (jq -r .Credentials.SecretAccessKey $json_file)set -lx AWS_SESSION_TOKEN (jq -r .Credentials.SessionToken $json_file)imchamberendreturn 0endendif test -n "$_flag_c"return 0endecho "imaws: Initializing CLI session for $role_arn"set source_profile (grep -A5 "\[profile $profile_name\]" ~/.aws/config | grep source_profile | awk 'BEGIN { FS = " ?= ?" } ; { print $2 }')if test -n "$source_profile"set profile_stuff --profile=$source_profileset -x AWS_ACCESS_KEY_ID (grep -A3 "\[$source_profile\]" ~/.aws/credentials | grep aws_access_key_id | awk 'BEGIN { FS = " ?= ?" } ; { print $2 }')set -x AWS_PROFILE $source_profileset -x AWS_SECRET_ACCESS_KEY (grep -A3 "\[$source_profile\]" ~/.aws/credentials | grep aws_secret_access_key | awk 'BEGIN { FS = " ?= ?" } ; { print $2 }')set login_account_alias (aws iam list-account-aliases | jq -r '.AccountAliases[0]')endif test -z "$AWS_ACCESS_KEY_ID" -o -z "$AWS_SECRET_ACCESS_KEY" -o -z "$login_account_alias"echo "imaws: Failed to obtain credentials for source profile $source_profile; cannot perform STS operations"return 1endset duration_seconds (grep -A5 "\[profile $profile_name\]" ~/.aws/config | grep duration_seconds | awk 'BEGIN { FS = " ?= ?" } ; { print $2 }')if test -z "$duration_seconds"set duration_seconds 43200endset -l mfa_stuff ""if test -n "$mfa_serial"set -l aws_email (echo $mfa_serial | cut -d/ -f2)set -l mfa_code 'unknown'if which -s op; and op item list | grep -q "AWS ($aws_email)"echo "+ op item get \"AWS ($aws_email)\""set mfa_code (op item get "AWS ($aws_email)" | grep 'one-time password:' | cut -b25-)else if which -s ykmanecho "+ ykman oath accounts code --single AWS:$login_account_alias"set mfa_code (ykman oath accounts code --single AWS:$login_account_alias)endif [ "$mfa_code" = "unknown" ]echo "imaws: Failed to obtain MFA code; sorry"return 2endset mfa_stuff --role-session-name=$aws_email --serial-number=$mfa_serial --token-code=$mfa_codeelseset mfa_stuff --role-session-name=(whoami)@(hostname)end# TODO: look into this alternate version# aws sts get-session-token $mfa_stuffecho "+ aws sts assume-role $profile_stuff --role-arn=$role_arn $mfa_stuff --output=json --duration-seconds=$duration_seconds"set -l session_json (aws sts assume-role --role-arn=$role_arn $mfa_stuff --output=json --duration-seconds=$duration_seconds)set -l sts_status $statusif test "$sts_status" -ne 0echo "imaws: Failed to obtain credentials ($sts_status); please try again"return 3elsemkdir -p (dirname $json_file)echo $session_json > $json_fileimaws $argv # recurse to pick up the cached credsreturn 0endend
# Install Ruby/Javascript project dependencies in PWD.function iif test -f Gemfilebundle check || bundle installendif test -f package.jsonset -l pmgr (cat package.json | jq -r .packageManager)switch $pmgrcase 'npm*'npm installcase 'yarn*'yarn installcase '*'if test -f package-lock.jsonnpm installelse if test -f yarn.lockyarn installelseecho "i: Dunno how to install; please add packageManager to package.json"return 1endendendend
# Supported syntax (& search priority):# g foobar --> chdir to foobar relative to pwd, if exists# g xyz --> chdir to some project names x*_y*_z* or x*-z*-y*function g# Search well-known GitHub ownersset -l bases $HOME/Code/AppFolio-IM $HOME/Code/xeger $HOME/Code/onthespotqa $HOME/Code/appfolio# If we're inside a Git (mono)repo, search top-level subdirs firstset -l toplevel (git rev-parse --show-toplevel 2> /dev/null)if test -n "$toplevel"set subdirs $toplevel/*set subdirs $subdirs[-1..1]for entry in $subdirsif test -d $entry && not git check-ignore -q $entryset -p bases $entryendendendset -l initials (echo "^$argv[1]" | sed -e 's/[A-Za-z]/&[^_-]*[_-]/g' | sed -e 's/\[_-\]$//')# Check whether this is a shortcut for some source-code project.for base in $basesset -l dirents $base/*for dir in $direntsif test -d $dirset -l bn (basename $dir)if test $bn = $argv[1] # exact matchcd $dirreturn 0else if echo $bn | grep -qE $initials # initials matchcd $dirreturn 0endendendend# Check whether this is the literal name of some directoryif test -d $argv[1]cd $argv[1]return 0end# No matches! Display error message.echo "Could not find a directory matching '$argv[1]' under any of:"for base in $basesecho " $base"endreturn 1end
function exportifyrm -f index.tsfor f in *.ts *.tsxif string match -q '*.config.ts' $fcontinueendset -l base (path change-extension '' $f)if grep -q 'export default' $fecho "export { default as $base } from './$base';" >> index.tsendecho "export * from './$base';" >> index.tsendend
function eksargparse --name=eks 'n/namespace' 'r/region' -- $argvor returnset cluster "$argv[1]"if test -n "$_flag_n"set namespace $_flag_nendset -q region $_flag_ror set region "us-east-2"if test -z $clusterecho "usage: eks <cluster>"echo " available clusters (aws eks list-clusters --region=$region):"aws eks list-clusters --region=$region | jq -r '.clusters | map(" - " + .) | .[]'return 1endecho "+ aws eks --region $region update-kubeconfig --name $cluster"aws eks --region $region update-kubeconfig --name $clustersed "s!command: aws!command: $HOME/.config/fish/scripts/imaws-wrapper!g" ~/.kube/config > ~/.kube/config.tmpmv ~/.kube/config.tmp ~/.kube/configchmod go-rwx ~/.kube/configecho "Updated ~/.kube/config to use imaws-wrapper"if test -n "$namespace"echo "+ kubectl config set-context (kubectl config current-context) --namespace=$namespace"kubectl config set-context (kubectl config current-context) --namespace=$namespaceendend
function dshset -l search $argv[1]set -l candidates (docker ps --format '{{.Names}}' | grep $search)if test (count $candidates) -eq 1docker exec -t -i $candidates[1] /bin/sh -c '[ -f /bin/bash ] && exec /bin/bash -l || exec /bin/sh -l'else if test (count $candidates) -eq 0docker exec -t -i $search /bin/sh -c '[ -f /bin/bash ] && exec /bin/bash -l || exec /bin/sh -l'elseecho "Too many containers match '$search'; please be more specific to disambiguate between:"for cand in $candidatesecho " $cand"endendend
function dockswitch $argv[1]case localhostset -ex DOCKER_HOSTcase developmentset -gx DOCKER_HOST "tcp://10.105.8.128:3376"case '*'set -gx DOCKER_HOST "tcp://$argv[1]:2376"endecho "DOCKER_HOST is $DOCKER_HOST"docker version | grep -A10 Serverend
function dlset -l cnt (count $argv)set -l search $argv[$cnt]set --erase argv[$cnt]set -l candidates (docker ps --format '{{.Names}}' | grep $search)if test (count $candidates) -eq 1docker logs $argv $candidates[1]else if test (count $candidates) -eq 0docker logs $argv $searchelseecho "Too many containers match '$search'; please be more specific to disambiguate between:"for cand in $candidatesecho " $cand"endendend
function dgcset -l ids (docker ps --filter="status=exited" --format="{{.ID}}")echo "Remove exited containers:"for id in $idsdocker rm -v $idendecho "Prune unused volumes:"docker volume prune -fend
function coverginkgo -r -randomizeAllSpecs -randomizeSuites -coverrm -f merged.coverprofilegocovmerge (find . -iname '*.coverprofile') > merged.coverprofilego tool cover -html=merged.coverprofileend
# Run rubocop only on specified paths or staged changes; fallback to run on everything.function copset -l pathsif test -n "$argv"set paths $argvelseset -l prefix (git rev-parse --show-prefix)set paths (git diff --cached --name-status --relative=$prefix | grep '^[AM].*[.]rb$' | cut -f 2)endecho "+ bundle exec rubocop -A $paths"bundle exec rubocop -A $pathsend
# Open a browser displaying the continuous integration status of the active branch.function ciset -l root (git rev-parse --show-toplevel)set -l remote (git remote -v | grep -E '^origin.*push' | sed 's|^.*github.com[:/]\(.*\)\.git.*$|\1|')set -l org (echo $remote | cut -d/ -f1)set -l repo (echo $remote | cut -d/ -f2)set -l branch (git symbolic-ref HEAD 2>/dev/null | sed -e 's:refs/heads/::')if test -d $root/.circleciopen "https://circleci.com/gh/$org/workflows/$repo/tree/$branch"elseopen "https://github.com/$org/$repo/tree/$branch"endend
# Force-push the working branch to its remote tracking branch at origin.function bumpset pushmode (git config push.default)if test $pushmode = simplegit push --force-with-leasereturn 0elseecho "bump: Cannot force-push; please `git config --global push.default simple`"return 1endend
#AWSume alias to source the AWSume scriptalias awsume="source (which awsume.fish)"
function HEADgit log -1 --format=%H $argvend
######## basic Unix stuff: editor, terminal, etcset -x EDITOR vi# clean start (avoid Visual Studio Code bugs w/ path duplication)if test -f /etc/pathsset -x PATH (cat /etc/paths | tr '\n' ':' | sed -Ee '$ s/:+$//')endalias psx 'pstree -U -g 2 %self'alias lsx 'tree -A -C -L 2'######## sshif test -n "$SSH_AUTH_SOCK"set -l private_keys (grep -El 'BEGIN [A-Z]* ?PRIVATE KEY' ~/.ssh/*)if test $status = 0; and test -n "$private_keys"ssh-add $private_keys 2> /dev/nullif test $status != 0echo "Could not add private SSH keys to agent"echo "Please run this command by hand:"echo "ssh-add $private_keys"endendendif test -d ~/java/apache-maven-3.9.2/binset -x PATH $PATH $HOME/java/apache-maven-3.9.2/binend######## google goif test -d ~/go/binset -x GOPATH ~/goset -x PATH $PATH ~/go/binlaunchctl setenv PATH (string join ':' $PATH) GOPATH $GOPATHend######## python (on Mac OS X, i.e. `/usr/bin/pip3 install xyz`)set -l pybin $HOME/Library/Python/3.*/binif test -n "$pybin"set -x PATH $PATH $pybinendset -e pybin######## ruby# only works with Ruby 2.7 (not OS X builtin Ruby, blech)set -x RUBYOPT "-W:no-deprecated"#set -x RUBYOPT "-W0"# seems to be actively harmful under Mojave w/ ruby 2.3.x# does not harm Ruby 2.5#if test -d /usr/local/opt/openssl# set -x RUBY_CFLAGS -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib#end######## rust# shrink rust installs with `asdf install rust` (and similar commands)set -x RUST_WITHOUT "rust-docs"if test -d ~/.cargo/binset -x PATH $PATH ~/.cargo/binend######## dockeralias darch 'docker inspect -f "{{.Architecture}}"'alias dc 'docker-compose'alias dcb 'docker-compose build'alias dcr 'docker-compose run'alias di 'docker inspect'alias dim 'docker images'alias dn 'docker network'alias dps 'docker ps'alias drm 'docker rm -f'alias drmi 'docker rmi'alias dv 'docker volume'alias dst 'docker stack'alias ds 'docker service'alias dsi 'docker service inspect --pretty'alias dtty 'nc -U ~/Library/Containers/com.docker.docker/Data/debug-shell.sock'######## Kubernetesalias kc 'kubectl'######## google cloud SDKif [ -f '/Users/tony/google-cloud-sdk/path.fish.inc' ]if type source > /dev/nullsource '/Users/tony/google-cloud-sdk/path.fish.inc'else. '/Users/tony/google-cloud-sdk/path.fish.inc'endend######## gitif [ ! -f '$HOME/.gitignore' ]touch $HOME/.gitignoreecho ".DS_Store" >> $HOME/.gitignoreendalias fetch='git fetch'alias gb='git branch'alias gco='git checkout'alias gcp='git cherry-pick'alias gd='git diff'alias gdc='git diff --cached'alias gl='git log --topo-order --pretty=format:"%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset" --abbrev-commit'alias glp='git log --topo-order --pretty=format:"%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%G?:%an>%Creset" --abbrev-commit'alias gss='git status'alias gsw='git show'alias sclear='git stash clear'alias slist='git stash list'alias spush='git stash save'alias spop='git stash pop'# git prompt lifted from http://goo.gl/Wq5lb7set normal (set_color normal)set magenta (set_color magenta)set yellow (set_color yellow)set green (set_color green)set red (set_color red)set gray (set_color -o black)# Fish git promptset __fish_git_prompt_showdirtystate 'yes'set __fish_git_prompt_showstashstate 'yes'set __fish_git_prompt_showuntrackedfiles 'yes'set __fish_git_prompt_showupstream 'yes'set __fish_git_prompt_color_branch yellowset __fish_git_prompt_color_upstream_ahead greenset __fish_git_prompt_color_upstream_behind red# Status Charsset __fish_git_prompt_char_dirtystate '⚡ 'set __fish_git_prompt_char_stagedstate '📌 'set __fish_git_prompt_char_untrackedfiles '💩 'set __fish_git_prompt_char_stashstate '↩'set __fish_git_prompt_char_upstream_ahead '⋙'set __fish_git_prompt_char_upstream_behind '⋘'function fish_promptset last_status $statusset_color $fish_color_cwdprintf '%s' (prompt_pwd)set_color normalset danger ''set here (basename $PWD)if git add -n ../$here 2>&1 | grep -q 'are ignored'set danger ' ⚠️ ️'endprintf '%s%s ' $danger (__fish_git_prompt)set_color normalend######## terraformalias tf='terraform'######## local config that should not be committed to gitif [ -f ~/.config/fish/local.fish ]source ~/.config/fish/local.fishend######## tool version managers (even for non-interactive shells!)if test -d ~/.asdfset -x PATH ~/.asdf/shims $PATHif status --is-interactiveif test -f /usr/local/share/fish/vendor_completions.d/asdf.fishsource /usr/local/share/fish/vendor_completions.d/asdf.fishendendend######## VS Codestring match -q "$TERM_PROGRAM" "vscode"and . (code --locate-shell-integration-path fish)
#Auto-Complete function for AWSumecomplete --command awsume --arguments '(awsume-autocomplete)'
This is my preferred fish configuration.Please refer to [dotfiles](https://github.com/xeger/dotfiles) for installation instructions.
.git.DS_Storefish_historyfish_read_historyfish_variablesfishd*local.fish
.pijul.DS_Storefish_historyfish_read_historyfish_variablesfishd*local.fish