ʕ≧ᴥ≦ʔ Rodrigo's blog

Windows Terminal com Gatinhos

Não, você não leu errado. O meu Windows Terminal tem gatinhos passeando na barra de títulos.

image 01

E caso algum comando não reconhecido seja digitado, o gatinho para de andar em frente à um ponto de exclamação.

image 02

Neste artigo mostrarei como você pode confirar o seu.

Requisitos

  1. Windows Terminal
  2. PowerShell
  3. DynamicTitle PowerShell Module

Instalação do Windows Terminal

O Windows Terminal é um novo aplicativo de terminal moderno e open source para shells de linha de comando como Command Prompt, PowerShell e WSL. Possui interessantes recursos como guias, painéis, suporte a caracteres Unicode e UTF-8 e um mecanismo de renderização de texto acelerado por GPU. A instalação recomendável é via Microsoft Store, assim você estará sempre com última versão do aplicativo uma vez que é atualizada automaticamente.

O Windows Terminal permite inúmeras configurações personalizadas como, por exemplo, temas, estilos e configurações personalizados, no entanto, o foco desse artigo será a customização da barra de títulos com gatinhos.

Instalação do PowerShell

O PowerShell é uma solução de automação de tarefas multiplataforma que consiste em um shell de linha de comando, em uma linguagem de script e uma estrutura de gerenciamento de configuração.

A instalação do PowerShell não é necessariamente um requisito imprescindível para este guia, pois o Windows já possui com o Windows PowerShell nativamente e que também funciona no Windows Terminal e portanto funciona para a customização que irei mostrar. No entanto, é importante ressaltar a diferença entre o Windows PowerShell e o PowerShell.

O Windows PowerShell (powershell.exe) é a versão do PowerShell que é fornecida no Windows e é somente executada no Windows. A versão mais recente é o Windows PowerShell 5.1 que não está mais sendo atualizada com novos recursos o que inclusive é mostrado na mensagem de boas vindas:

image 03

O PowerShell (pwsh.exe) é a solução moderna, open-source e está repleto de melhorias e novas funcionalidades. O PowerShell pode ser executado no Windows, Linux e macOS. Por isso, para é recomendável usar o PowerShell ao invés do Windows PowerShell.

image 04

Para instalar o PowerShell basta baixar o pacote de instação, clicar duas vezes no arquivo de instalação e seguir as instruções.

Instalação do módulo DynamicTitle

No PowerShell, módulos são pacotes ou bibliotecas de cmdlets, provedores, funções, classes, variáveis e aliases.

Para colocarmos gatinhos na barra de títulos do Windows Terminal, precisamos instalar o módulo DynamicTitle que contém os comandos (que em PowerShell são chamados de cmdlets) necessários para a customização. Para isso você precisa rodar o comando abaixo:

Install-Module -Name DynamicTitle

Uso básico

Primeiramente temos que carregar o módulo em memória para disponibilizar os cmdlets a serem utilizados:

Import-Module -Name DynamicTitle

Este comando mostra a data e hora na barra de título.

Start-DTTitle {Get-Date}

image 05

Para mostrar a hora atualizada o ScriptBlock especificado é chamado periodicamente num determinado intervalo numa thread em segundo plano. O módulo define o título do console como a cadeia de caracteres devolvida pelo ScriptBlock.

No repositório do DynamicTitle tem mais exemplos de como utilizá-lo.

Colocando os gatinhos para passear na barra de títulos

Primeiramente, vamos configurar o perfil. Um perfil do PowerShell é um script que é executado quando o PowerShell é iniciado. Usaremos o perfil para personalizar o Windows Terminal assim que iniciado.

Para editar o perfil, digite:

notepad $PROFILE

Um arquivo chamado Microsoft.PowerShell_profile.ps1 é aberto no bloco de notas. Insira o trecho de código abaixo, salve e feche o arquivo.

É necessário fechar e abrir o Windows Terminal para que as mudanças no perfil tenham efeito.

Import-Module -Name DynamicTitle

$promptJob = Start-DTJobPromptCallback {
   if ($null -eq $script:terminalCatPromptFrame) {
       $script:terminalCatPromptFrame = 0
   }
   $script:terminalCatPromptFrame++

   $isInError = $false
   if ($Error[0]) {
       $isInError = -not ($Error[0].Equals($script:terminalCatLastError))
       $script:terminalCatLastError = $Error[0]
   }
   $isInError, $script:terminalCatPromptFrame
}

$initializationScript = {
   $mainTitle = '  PowerShell  '
   $characters = @(
       '🐈'
       '🐈‍⬛'
   )
   $caution = '❕'

   $streetParts = @(
       '_._._.'
       '_.-._'
   )
   $streetLength = 2

   function GetCharacter {
       $characters | Get-Random
   }
   function GetStreet {
       $street = ''
       foreach ($i in 1..$streetLength) {
           $street += $streetParts | Get-Random
       }
       $street
   }
   function GetWaitFrame {
       Get-Random -Minimum 0 -Maximum 100
   }

   $character = GetCharacter
   $streetL = GetStreet
   $streetR = GetStreet
   $waitFrame = GetWaitFrame
   $characterPos = 1
   $lastPromptFrame = 0
   $isCaution = $false
}

$scriptBlock = {
   param($promptJob)

   $isInError, $promptFrame = Get-DTJobLatestOutput $promptJob
   if ($isInError -and ($promptFrame -ne $script:lastPromptFrame)) {
       $script:isCaution = $true
   }
   if (-not $isInError) {
       $script:isCaution = $false
   }
   $script:lastPromptFrame = $promptFrame

   $title = $streetL + $mainTitle + $streetR
   if ($script:waitFrame -gt 0) {
       $script:waitFrame--
       $script:isCaution = $false
       $title
       return
   }

   $stringInfo = [System.Globalization.StringInfo]::new($title)
   $length = $stringInfo.LengthInTextElements
   $characterIndex = $length - 1 - $script:characterPos

   if ($script:isCaution) {
       if ($characterIndex -ge 1) {
           $characterIndex -= 1
           $character = $caution + $character
       } else {
           $character = $character + $caution
       }
       $title = $stringInfo.SubstringByTextElements(0, $characterIndex) + $character + $stringInfo.SubstringByTextElements($characterIndex + 2)
   } else {
       $title = $stringInfo.SubstringByTextElements(0, $characterIndex) + $character + $stringInfo.SubstringByTextElements($characterIndex + 1)
       $script:characterPos += 1
       if ($script:characterPos -ge $length) {
           $script:characterPos = 1
           $script:waitFrame = GetWaitFrame
           $script:character = Getcharacter
       }
   }
   $title
}

$params = @{
   InitializationScript = $initializationScript
   ScriptBlock = $scriptBlock
   ArgumentList = $promptJob
}

Start-DTTitle @params

Para entender o código acima é necessário um pouco de conhecimento da linguagem script em PowerShell mas, em uma visão geral, setamos as três variáveis que são passadas como paramêtro para o cmdlet Start-DTTitle.

image 06

Parabéns! Você agora tem a companhia de gatinhos e não está mais sozinho. 😄

O que achou deste post? 😊😐☹️