Skip to content

Instantly share code, notes, and snippets.

@AstDerek
Created November 4, 2012 19:17
Show Gist options
  • Save AstDerek/4013164 to your computer and use it in GitHub Desktop.
Save AstDerek/4013164 to your computer and use it in GitHub Desktop.
Editor de texto simple
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*#define TECLA_ARRIBA 72*/
/*#define TECLA_ABAJO 80*/
/* El programa fue probado a través de SSH, no funcionan las flechas */
#define TECLA_ARRIBA 'r'
#define TECLA_ABAJO 'b'
#define TECLA_IZQUIERDA 75
#define TECLA_DERECHA 77
#define ANCHO_LINEA 61
#define NUMERO_LINEAS 20
static FILE *archivo = NULL;
char nombre[256];
typedef struct eslabon {
struct eslabon *siguiente;
char linea[ANCHO_LINEA];
unsigned short caracteres;
} segmento;
segmento *contenido_archivo = NULL, *final_archivo = NULL;
unsigned long lineas_totales = 0;
unsigned long linea_actual = 0;
void flush () {
getchar();
}
void limpiar_lista () {
segmento *segmento_actual = contenido_archivo, *segmento_siguiente;
while (segmento_actual) {
segmento_siguiente = segmento_actual->siguiente;
free(segmento_actual);
segmento_actual = segmento_siguiente;
}
contenido_archivo = NULL;
final_archivo = NULL;
}
segmento * agregar_nodo () {
segmento *nuevo_segmento;
nuevo_segmento = (segmento *)calloc(1,sizeof(segmento));
nuevo_segmento->siguiente = NULL;
nuevo_segmento->caracteres = 0;
memset(nuevo_segmento->linea,0,ANCHO_LINEA);
lineas_totales++;
if (!contenido_archivo) {
contenido_archivo = nuevo_segmento;
final_archivo = nuevo_segmento;
}
else {
final_archivo->siguiente = nuevo_segmento;
final_archivo = nuevo_segmento;
}
return nuevo_segmento;
}
segmento * buscar_nodo (unsigned long posicion) {
unsigned long contador = 0;
segmento *segmento_actual;
if (posicion == 0) {
return contenido_archivo;
}
segmento_actual = contenido_archivo;
while (segmento_actual && contador < posicion) {
segmento_actual = segmento_actual->siguiente;
contador++;
}
return segmento_actual;
}
void borrar_nodo () {
segmento *segmento_actual, *segmento_anterior = NULL;
segmento_actual = contenido_archivo;
if (!segmento_actual) {
return;
}
else if (!segmento_actual->siguiente) {
free(segmento_actual);
contenido_archivo = NULL;
final_archivo = NULL;
return;
}
while (segmento_actual->siguiente) {
segmento_anterior = segmento_actual;
segmento_actual = segmento_anterior->siguiente;
}
free(segmento_actual);
segmento_anterior->siguiente = NULL;
final_archivo = segmento_anterior;
lineas_totales--;
}
void mostrar_archivo () {
unsigned long contador;
segmento *segmento_actual;
if (linea_actual >= lineas_totales - NUMERO_LINEAS) {
linea_actual = lineas_totales - NUMERO_LINEAS;
}
else if (linea_actual < 0) {
linea_actual = 0;
}
segmento_actual = buscar_nodo(linea_actual);
for (contador=0;segmento_actual && contador<NUMERO_LINEAS;contador++) {
printf("%02d: %s\n",linea_actual + contador + 1,segmento_actual->linea);
segmento_actual = segmento_actual->siguiente;
}
if (!lineas_totales) {
printf("<Buffer vacio>\n");
}
printf("\n");
}
void guardar_archivo () {
segmento *segmento_actual;
if (archivo) {
segmento_actual = contenido_archivo;
fseek(archivo,0L,SEEK_SET);
while (segmento_actual) {
if (segmento_actual->caracteres) {
fwrite(segmento_actual->linea,segmento_actual->caracteres,1,archivo);
}
else {
fwrite("\n",1,1,archivo);
}
segmento_actual = segmento_actual->siguiente;
}
}
}
void cerrar_archivo () {
if (archivo) {
fclose(archivo);
archivo = NULL;
}
}
char * capturar_nombre () {
memset(nombre,0,256);
printf("Nombre del archivo: ");
fgets(nombre,255,stdin);
if (strlen(nombre)) {
nombre[strlen(nombre) - 1] = 0;
}
return nombre;
}
void leer_archivo () {
unsigned long c, n=0;
segmento *ultimo_segmento;
limpiar_lista();
if (!archivo) {
return;
}
while (!feof(archivo) && !ferror(archivo) && n++<100) {
ultimo_segmento = agregar_nodo();
if (NULL == fgets(ultimo_segmento->linea,ANCHO_LINEA,archivo)) {
borrar_nodo();
break;
}
ultimo_segmento->caracteres = strlen(ultimo_segmento->linea);
if (ultimo_segmento->linea[ultimo_segmento->caracteres - 1] == '\n') {
ultimo_segmento->caracteres -= 1;
ultimo_segmento->linea[ultimo_segmento->caracteres] = 0;
if (ultimo_segmento->caracteres) {
agregar_nodo();
}
}
}
ultimo_segmento = contenido_archivo;
}
void abrir_archivo () {
cerrar_archivo();
archivo = fopen(capturar_nombre(),"r+");
leer_archivo();
}
void agregar_nueva_linea () {
agregar_nodo();
mostrar_archivo();
}
void borrar_ultima_linea () {
borrar_nodo();
mostrar_archivo();
}
void mover_arriba () {
if (linea_actual) {
linea_actual--;
}
mostrar_archivo();
}
void mover_abajo () {
if (linea_actual < lineas_totales - NUMERO_LINEAS) {
linea_actual++;
}
mostrar_archivo();
}
void mover_izquierda () {
mostrar_archivo();
}
void mover_derecha () {
mostrar_archivo();
}
short salir (short estado) {
static short confirmar = 0;
if (estado) {
confirmar = 1;
}
return confirmar;
}
char leer_opcion () {
char tecla = ' ';
tecla = getchar();
if (tecla == 0 || tecla == 224) {
tecla = getchar();
}
flush();
return tecla;
}
short procesar_menu () {
char tecla = ' ';
tecla = leer_opcion();
switch (tecla) {
case 'o':
abrir_archivo();
break;
case 'i':
agregar_nueva_linea();
break;
case 'd':
borrar_ultima_linea();
break;
case 's':
guardar_archivo();
break;
case 'q':
salir(1);
break;
case TECLA_ARRIBA:
mover_arriba();
break;
case TECLA_ABAJO:
mover_abajo();
break;
case TECLA_IZQUIERDA:
mover_izquierda();
break;
case TECLA_DERECHA:
mover_derecha();
break;
default:
return 0;
}
return 1;
}
void mostrar_menu () {
char *menus[] = {
"q - Salir",
"o - Abrir archivo",
"i - Agregar nueva linea",
"d - Borrar ultima linea",
"s - Guardar archivo",
"r - Desplazar hacia arriba",
"b - Desplazar hacia abajo"
};
short c, n, t, total = 7;
total = strlen(nombre) ? total : 2;
system("clear");
for (c=0;c<total;c++) {
printf("+");
for (n=0;n<strlen(menus[c])+2;n++) {
printf("-");
}
}
printf("+\n");
for (c=0;c<total;c++) {
printf("| %s ",menus[c]);
}
printf("|\n");
for (c=0;c<total;c++) {
printf("+");
for (n=0;n<strlen(menus[c])+2;n++) {
printf("-");
}
}
printf("+\n");
if (strlen(nombre)) {
printf("\nArchivo: %s\n",nombre);
}
printf("\n");
}
int main (int narg, char *varg[]) {
mostrar_menu();
printf("Opcion: ");
while (!salir(0)) {
if (procesar_menu()) {
mostrar_menu();
mostrar_archivo();
printf("Opcion: ");
}
}
printf("\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment