📄 edit.c
字号:
////////////////////////////////////////////////////////////////
//
// S C R I P T H E R M
// A SCRIPTABLE THERMOMETER
//
// entry of the National Semiconductor COP8FLASH Design Contest
// submitted by Alberto Ricci Bitti (C) 2001
// a.riccibitti@ra.nettuno.it
//
//--------------------------------------------------------------
// FOR A BETTER VIEW SET TAB SIZE=4, INDENT SIZE=4
//--------------------------------------------------------------
// FILE : edit.c
// PURPOSE: Simple full-screen editor for small files.
// Very portable, just redefine peek_ram() and
// poke_ram() to suit your edit buffer
// implementation.
//
////////////////////////////////////////////////////////////////
#include "types.h"
#include "ascii.h"
#include "serial.h"
#include "memory.h"
#include "lcd.h"
#include "main.h"
#include "edit.h"
// codes used for full screen navigation and for deleting a character
#define KEY_BACKSP 0x7F
#define KEY_UP 0x0B
#define KEY_DOWN 0x0A
#define KEY_LEFT 0x08
#define KEY_RIGHT 0x09
#define KEY_CANC 0x18
static unsigned int first_visible = 0; //address of the first visible line
static unsigned int current = 0; //cursor address
static unsigned char modified = 0; //flags buffer changes
//given an address, returns the beginning of the line that incudes it
static unsigned int line_start( unsigned int pos)
{
while (pos > 0)
{
if ( peek_ram(--pos) == END_OF_LINE )
{ pos++; break; };
};
return pos;
}
//given an address, returns the position of next line start
static unsigned int next_line(unsigned int pos)
{ unsigned char c;
c = peek_ram(pos);
while( (c != 0) && (c != END_OF_LINE) )
{
c = peek_ram(++pos);
};
if (c != 0)
pos++;
return pos;
}
static void cursor_forward(void)
{
if ( peek_ram(current) != 0 )
current++;
}
static void cursor_back(void)
{
if (current > 0)
current--;
}
static void cursor_up(void)
{
cursor_back();
current = line_start( current );
}
static void cursor_down(void)
{
current = next_line( current );
}
//inserts a character at current cursor position
static void ins(unsigned char replacer)
{
unsigned int pos = current;
unsigned char replaced;
if (current < RAM_SIZE -1)
{
modified = 1;
while (1)
{
replaced = peek_ram(pos);
poke_ram(pos++, replacer);
if (replacer == 0)
break;
replacer = replaced;
};
}
cursor_forward();
}
//deletes a character at the current cursor position
static void del(void)
{
unsigned int pos = current;
modified = 1;
while (peek_ram(pos) != 0)
{
poke_ram( pos, peek_ram(pos+1) );
pos++;
}
}
// redraws the screen
static void refresh(void)
{
unsigned int i;
unsigned char r=0, c=0, char_buf;
//if current not shown, scroll window back
while (first_visible > current)
first_visible = line_start( --first_visible );
do
{
i = first_visible;
LCD_locate(0,0);
do
{
//take note of cursor position
if (i==current) { r = cursor_row; c = cursor_col; };
char_buf = peek_ram(i);
//in case replace end of file with end of line
LCD_putchar( (unsigned char) (char_buf ? char_buf : END_OF_LINE) );
i++;
//repeat until buffer end or screen end
} while ( ! (char_buf == 0 || cursor_row == 0 && cursor_col == 0) );
//if current not shown, scroll window forward and repeat
if (i <= current)
{
first_visible = next_line( first_visible );
continue;
};
} while (i <= current);
//clear space to end of screen...
while(cursor_row != 0 || cursor_col != 0)
LCD_putchar(' ');
//...and restore cursor
LCD_locate(r,c);
LCD_move_cursor(r,c);
}
//full screen edit, places the cursor to the specified position
unsigned char edit_program(unsigned int cursor)
{
unsigned int k;
modified = 0;
current = cursor;
first_visible = line_start(cursor);
LCD_clear_text();
do
{
if ( !com_pending() ) refresh();
while( !com_pending() && flags.program)
{ /* loop intentionally void*/ };
if (! flags.program)
{
//tricky: hide cursor
LCD_move_cursor(0, 40);
return modified;
};
switch( k = com_getchar() )
{
case KEY_UP:
cursor_up();
break;
case KEY_DOWN:
cursor_down();
break;
case KEY_LEFT:
cursor_back();
break;
case KEY_RIGHT:
cursor_forward();
break;
case KEY_CANC:
del();
break;
case KEY_BACKSP:
if (current > 0)
{
cursor_back();
del();
};
break;
case END_OF_LINE:
ins( END_OF_LINE );
break;
default:
if ( k > 31 && k < 128 )
ins( (unsigned char) k );
break;
};
} while (1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -