Estou seguindo o tutorial Build Your Own Text Editor para construir um editor de texto simples em C, chamado Kilo. O objetivo é entender conceitos fundamentais de programação de baixo nível e manipulação de terminal.
Manipulação de Terminal em Modo Raw
Uma das primeiras coisas que aprendi foi como manipular o terminal no chamado modo raw (ou "modo cru"). Diferente do comportamento padrão do terminal, onde a entrada é processada linha a linha, o modo raw nos dá controle direto sobre cada tecla pressionada.
No Unix/Linux, o terminal normalmente opera em modo canônico (cooked mode), onde a entrada só é enviada ao programa quando o usuário pressiona Enter. O modo raw permite capturar cada tecla imediatamente.
A Estrutura termios
Para manipular o terminal, utilizamos a estrutura termios
, que contém todas as configurações do terminal:
struct termios {
tcflag_t c_iflag; // flags de entrada
tcflag_t c_oflag; // flags de saída
tcflag_t c_cflag; // flags de controle
tcflag_t c_lflag; // flags locais
cc_t c_cc[NCCS]; // caracteres de controle
};
Configurando o Modo Raw
Para implementar o modo raw, precisamos desativar várias flags do terminal:
Flags desativadas
ECHO
: não mostra caracteres digitadosICANON
: desativa modo canônicoISIG
: desativa sinais como Ctrl+CIXON
: desativa controle XON/XOFFIEXTEN
: desativa sequências estendidasOPOST
: desativa processamento de saída
Bandeiras ativadas
CS8
: configura caracteres de 8 bitsVMIN = 0
: retorna imediatamente da leituraVTIME = 1
: timeout de 0.1 segundos
Aqui está o código que implementa o modo raw:
void enableRawMode() {
if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) die("tcgetattr");
atexit(disableRawMode);
struct termios raw = orig_termios;
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
raw.c_oflag &= ~(OPOST);
raw.c_cflag |= (CS8);
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
raw.c_cc[VMIN] = 0;
raw.c_cc[VTIME] = 1;
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) die("tcsetattr");
}
Usamos o operador bitwise &= ~
para desativar flags e |=
para ativá-las, sem afetar as outras flags.
Gerenciamento de Recursos
Uma parte importante da programação em C é o gerenciamento adequado de recursos. Nesse editor, registramos uma função disableRawMode()
com atexit()
para garantir que o terminal seja restaurado ao seu estado original quando o programa terminar:
void disableRawMode() {
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1)
die("tcsetattr");
}
Sempre restaure o estado original dos recursos que você modificar, mesmo em caso de erro ou término abrupto do programa.
Tratamento de Erros
O código também implementa uma função die()
para tratamento de erros:
void die(const char *s) {
perror(s);
exit(1);
}
Esta função usa perror()
para exibir uma mensagem de erro descritiva baseada no valor atual de errno
, e então termina o programa com código de erro.
Conceitos Fundamentais Aprendidos
Conceito | Descrição |
---|---|
Modo Terminal | Diferença entre modo canônico e modo raw |
Estrutura termios | Como configurar o comportamento do terminal |
Tratamento de Erros | Uso de errno e perror() para diagnosticar problemas |
Manipulação de Bits | Uso de operadores bitwise para modificar flags |
Gerenciamento de Recursos | Importância de restaurar estados originais |
Próximos Passos
Nos próximos capítulos do tutorial:
- Entrada e exibição de texto
- Manipulação do cursor
- Operações de edição (inserir, excluir texto)
- Operações de arquivo (abrir, salvar)
- Busca e destaque de sintaxe
Recursos
Se você quiser acompanhar meu progresso ou ver o código-fonte completo, confira:
- Meu repositório: GitHub - Kilo Editor
- Tutorial original: Build Your Own Text Editor
- Documentação termios: Linux man page - termios