Explorando o "Fim da Linha" em seus projetos.

Parece coisa boba, mas o fim de linha de um arquivo é um detalhe técnico que tem sua devida importância, especialmente em projetos colaborativos. Entender alguns conceitos, assim como o funcionamento e seus impactos é essencial para garantir projetos mais robustos, colaborativos e compatíveis com diferentes plataformas.

EOL - End Of Line

📄 Quando a gente digita um texto e pressiona Enter para iniciar uma nova linha, o que na verdade acontece nos bastidores é a inserção de um caractere especial que marca o término da linha. Sem esse caractere, um arquivo seria apenas uma sequência interminável de texto.

O Git, por exemplo, espera que os arquivos de texto do projeto estejam com o fim da linha definido. Inconsistências nesse aspecto podem gerar conflitos ao fazer commits, merges ou até mesmo na simples visualização das diferenças entre versões de arquivos.

Esses caracteres são padrões de End Of Line (EOL) e definem como o sistema deve tratar o comportamento da quebra de linha. O caractere invisível usado é chamado de Newline, e é o que faz o sistema entender onde será o ponto de quebra naquele arquivo para começar uma nova linha, defindo que uma linha terminou.

Editores de codigo escondem, e tornam invisível o caractere de fim da linha, porém eles podem ser representados como Strings ou ASCII: 0x0D 0x0A \r \n e etc.

⚙️ Essa convenção de Newline em arquivos de texto surgiu no UNIX, e indica que o arquivo terminou por completo. Porém, há diferentes abordagens para esses padrões de caracteres de controle que marcam a quebra de linha em um arquivo de texto: CR e LF.

CR = Carriage Return

  • Este caractere move o cursor para o início da linha atual, sem avançar para a próxima linha. Antigamente, o Mac OS utilizava apenas CR.

LF = Line Feed

  • Este caractere move o cursor para baixo (linha seguinte). Ou seja, para a próxima linha, mas sem retornar ao início dessa linha. Este caractere é usado por padrão como caractere de nova linha em sistemas baseados em Unix/Linux.

É também utilizada a sequência CR + LF (CRLF), que é uma combinação dos dois acima. Ou seja, são usados dois caracteres de forma combinada. Nesse caso ele move o cursor para baixo, para a próxima linha, e também move para o início dessa linha. Este padrão é utilizado por exemplo no Windows.

No editor VS Code, é possível visualizar e alterar o padrão de fim de linha dos arquivos. Basta clicar no canto inferior direito da janela, onde o padrão atual de EOL é exibido.

EOL - Vs Code

Aplicação prática

🌱 Um exemplo de aplicação prática disso é que recetemente a ferramenta spring initializr (API que gera um projeto Spring Boot rapidamente) adotou como padrão a geração automática do arquivo .gitattributes, a fim de fazer correções de fim de linha, definindo o comportamento esperado do EOL para diferentes tipos de arquivos, garantindo consistência nos projetos e repositórios.

/mvnw text eol=lf
*.cmd text eol=crlf

Por exemplo, arquivos de scripts do Windows como bat e cmd precisam de CRLF, enquanto que comandos shell *.sh seguem o padrão LF.

O arquivo .gitattributes pode definir vários elementos, e é muito útil para estabelecer um padrão que os colaboradores devem seguir no repositório, independente de como a IDE/editor eteja configurada. Com esse arquivo, configurações do Git podem ser substituídas nos arquivos que tiverem o atributo EOL especificado no .gitattributes. E por isso muitas vezes você recebe no Git por exemplo warnings como:

"LF will be replaced by CRLF in <filename>."

Exemplos de Configuração:

text=auto: O Git manipula automaticamente os arquivos.

text eol=crlf: O Git sempre converterá delimitadores de linha em CRLF no check-out.

text eol=lf: O Git sempre converterá delimitadores de linha em LF no check-out.

A Origem do CR e LF

🧐 Por fim, uma curiosidade é que esses dois caracteres são expressões que tem origem nas antigas máquinas de escrever.

Carriage Return (CR): "Retorno do carro". Referência ao mecanismo que movia o cabeçote da máquina para o início da linha.

Line Feed (LF): Alimentava o papel para a próxima linha, movendo o papel para cima. Permitindo que o cabeçote da máquina ou o ponteiro continuasse imprimindo na linha seguinte.

Quando eu li "Fim da Linha" em seus projetos, eu pensei que você iria falar sobre "Quando um projeto seu chega oa fim ou dá errado" kkkkkk

Lembro de fazer alguns projetos em C que utilizavam bastante o caractere \n, tudo que eu fazia tinha que ir buscando até encontrar ele e passar por cada caractere da variavel