kolibrios/programs/fs/kfar/trunk/editor.inc

2573 lines
50 KiB
PHP
Raw Normal View History

virtual at 0
editor_data:
.hPlugin dd ?
.hFile dd ?
if (.hPlugin <> viewer_data.hPlugin) | (.hFile <> viewer_data.hFile)
error in viewer_IsHandleUsed/editor_IsHandleUsed
end if
.memsize dd ?
.encoding db ?
.flags db ? ; & 0x80: modified
; & 0x40: file is locked
; & 0x20: next key as a symbol
; & 0x10: replace mode (vs insert)
.eol db ?
rb 1
.first_block dd ?
.last_block dd ?
.numfree dd ?
.freeblocks dd ?
.numlines dd ?
.curline dd ?
.curcol dd ?
;.curpos_block dd ?
;.curpos_offs dd ?
.cur_block dd ?
.cur_offs dd ?
.cur_delta dd ?
.cursor_x dd ?
.cursor_y dd ?
align 200h
.filename rb 1024
.hostname rb 1024
if (.filename <> viewer_data.filename) | (.hostname <> viewer_data.hostname)
error in viewer_getname/editor_getname
end if
.buf rb 16384 ; all I/O operations use this buffer
.basesize = $
.linedata_start:
end virtual
virtual at 0
editor_line:
.block dd ?
.offs dw ?
;.length dd ?
.plugdata:
end virtual
; when a file is loaded into the editor, this file is fragmented to blocks
; each block has RESERVE_IN_BLOCK empty bytes to allow quick inserting
; must be dword-aligned!
edit.RESERVE_IN_BLOCK = 16
edit.eol_dos = 1 ; DOS/Win EOLn style (0D 0A)
edit.eol_unix = 2 ; Unix EOLn style (0A)
edit.eol_mac = 3 ; MacOS EOLn style (0D)
virtual at 0
edit_block_header:
.next dd ?
.prev dd ?
.limit dd ?
.size = $ ; must be dword-aligned
end virtual
edit_file:
mov eax, [ebp + panel1_files - panel1_data]
mov ecx, [eax+ecx*4]
test byte [ecx], 10h
jz .file
ret
.file:
; calculate required memory size
cmp dword [ecx+36], 0
jnz .nomemory
; block size = 4096
; block header: edit_block_header.size bytes
; some plugin-specific data can follow
; reserve RESERVE_IN_BLOCK free bytes in the end of block
mov ebx, 4096
mov eax, [EditPlugInfo]
add eax, edit_block_header.size
mov [EditBlockStart], eax
sub ebx, eax
sub ebx, edit.RESERVE_IN_BLOCK
mov [EditBlockSize], ebx
; now ebx = size of file data in each block
mov eax, [ecx+32]
; if eax == 0, set eax = 1
sub eax, 1
adc eax, 1
xor edx, edx
div ebx
sub edx, 1
sbb eax, -1
add eax, [EditDataSize]
; eax = number of blocks + memory for editor_data structure
cmp eax, 0x80000000 shr 12
jb .memok
.nomemory:
push aEditNoMemory
mov eax, esp
push ContinueBtn
push 1
push eax
push 1
call SayErr
pop eax
ret
.memok:
lea esi, [ebp + panel1_dir - panel1_data]
push eax
push ecx
mov ecx, eax
shl ecx, 12
mov edx, editor_vtable
call new_screen
pop ecx
pop ebx
test eax, eax
jnz @f
ret
@@:
mov [ebp + editor_data.memsize], ebx
mov al, [EditEOLStyle]
mov [ebp + editor_data.eol], al
mov eax, dword [esi + panel1_hPlugin - panel1_dir]
mov [ebp + editor_data.hPlugin], eax
test eax, eax
jz .nocopyhostname
lea edi, [ebp + editor_data.hostname]
push esi
mov eax, dword [esi + panel1_parents - panel1_dir]
mov esi, dword [esi + panel1_parents_sz - panel1_dir]
add esi, eax
@@:
dec esi
cmp byte [esi-1], 0
jz @f
cmp byte [esi-1], '/'
jnz @b
@@:
lodsb
stosb
test al, al
jnz @b
pop esi
.nocopyhostname:
mov eax, dword [esi + panel1_hFile - panel1_dir]
mov [ebp + editor_data.hFile], eax
mov [ebp + editor_data.encoding], encodings.cp866
xor eax, eax
mov [ebp + editor_data.flags], al
inc eax
mov [ebp + editor_data.numlines], eax
lea edi, [ebp + editor_data.filename]
mov ebx, readinfo
mov [ebx+21], edi
@@:
lodsb
test al, al
jz @f
stosb
jmp @b
@@:
lea esi, [ecx+40]
mov al, '/'
cmp byte [edi-1], al
jz @f
stosb
@@:
lodsb
stosb
test al, al
jnz @b
; load file into memory
mov esi, [ebp + editor_data.memsize]
mov edi, [EditDataSize]
sub esi, edi ; esi = number of blocks
shl edi, 12
;mov [ebp + editor_data.curpos_block], edi
mov [ebp + editor_data.first_block], edi
mov [ebp + editor_data.cur_block], edi
add edi, ebp ; edi -> first block
mov [ebp + editor_data.linedata_start + editor_line.block], edi
xor eax, eax
mov [ebx+4], eax
mov [ebx+8], eax
mov dword [ebx+12], 16384
lea eax, [ebp + editor_data.buf]
mov [ebx+16], eax
mov edx, [ebp + editor_data.hPlugin]
test edx, edx
jz @f
pushad
push O_READ
push dword [ebx+21]
push [ebp + editor_data.hFile]
call [edx + PluginInfo.open]
mov [esp+1Ch], eax
popad
test eax, eax
jz ..openerr_in_screen
mov ebx, eax
@@:
mov ecx, [EditBlockSize] ; bytes rest in the current block
add edi, [EditBlockStart]
.readloop:
mov edx, [ebp + editor_data.hPlugin]
test edx, edx
jz .readnative
pushad
push 16384
push [readinfo.data]
push ebx
call [edx + PluginInfo.read]
mov [esp+1Ch], eax
popad
cmp eax, -1
jnz .readok
; let us hope that plugin says error itself
push ebp
push ebx
call [edx + PluginInfo.close]
pop ebp
jmp .readfailed
.readnative:
push ebx
push 70
pop eax
int 40h
mov edx, ebx
xchg eax, edx
pop ebx
add dword [ebx+4], eax
adc dword [ebx+8], 0
test edx, edx
jz .readok
cmp edx, 6
jz .readok
push dword [ebx+21]
push aCannotReadFile
xchg eax, edx
call get_error_msg
push eax
mov eax, esp
push RetryOrCancelBtn
push 2
push eax
push 3
call SayErr
add esp, 3*4
test eax, eax
jz .readnative
.readfailed:
jmp delete_active_screen
.readok:
; eax = number of bytes read
test eax, eax
jnz @f
push edi
sub edi, ebp
cmp edi, [ebp + editor_data.first_block]
pop edi
jnz .readdone
@@:
push eax ebx
mov ebx, [readinfo.data]
.loadloop:
test ecx, ecx
jnz .hasplace
push eax
dec esi
jns .hasblock
add [ebp + editor_data.memsize], 8
add esi, 8
mov ecx, [ebp + editor_data.memsize]
cmp ecx, 80000000h shr 12
jb @f
.nomemory2:
pop eax ebx eax
call .nomemory
jmp .readfailed
@@:
sub edi, ebp
shl ecx, 12
mov edx, ebp
call xpgrealloc
test eax, eax
jz .nomemory2
add edi, eax
xchg ebp, eax
.hasblock:
push edi
and edi, not 0xFFF
lea eax, [edi + 0x1000]
sub eax, ebp
stosd ; edit_block_header.next
sub eax, 0x2000
stosd ; edit_block_header.prev
pop eax
sub eax, edi
add eax, 8
stosd ; edit_block_header.limit
mov ecx, [EditPlugInfo]
inc ecx
jz @f
dec ecx
@@:
xor eax, eax
rep stosb ; info for plugins: zeroed
add edi, 0x1000
mov ecx, [EditBlockSize]
pop eax
.hasplace:
push ecx
cmp eax, ecx
ja @f
mov ecx, eax
@@:
push ecx
push eax
push esi edi
mov esi, ebx
mov edx, ecx
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 3
rep movsb
mov ebx, esi
mov ecx, edx
pop esi
; calculate number of lines in this block
test ecx, ecx
jz .4
mov al, [esi - 1]
mov edx, esi
sub edx, [EditBlockStart]
test edx, 0xFFF
jnz .0
mov al, 0
sub edx, ebp
cmp edx, [ebp + editor_data.first_block]
jz .0
sub edx, 1000h
add edx, ebp
add edx, [edx + edit_block_header.limit]
mov al, [edx - 1]
.0:
xor edx, edx
cmp al, 13
jnz .1
mov dl, 10
.1:
mov al, [esi]
add esi, 1
cmp al, 13
jz @f
cmp al, 10
jz @f
mov dl, 0
sub ecx, 1
jnz .1
jmp .4
@@:
cmp al, dl
mov dl, 0
jz .3
add [ebp + editor_data.numlines], 1
cmp al, 10
jz .3
mov dl, 10
.3:
sub ecx, 1
jnz .1
.4:
pop esi
pop eax
pop ecx
sub [esp], ecx
sub eax, ecx
pop ecx
jnz .loadloop
pop ebx eax
cmp eax, 16384
jz .readloop
.readdone:
push edi
and edi, not 0xFFF
xor eax, eax
stosd ; editor_block_header.next
lea eax, [edi - 4 - 0x1000]
sub eax, ebp
stosd ; editor_block_header.prev
pop eax
sub eax, edi
add eax, 8
stosd ; editor_block_header.limit
mov ecx, [EditPlugInfo]
inc ecx
jz @f
dec ecx
@@:
xor eax, eax
rep stosb
and edi, not 0xFFF
lea ecx, [edi + 0x1000]
sub ecx, ebp
mov edx, ecx
shr ecx, 12
sub ecx, [ebp + editor_data.memsize]
neg ecx
mov [ebp + editor_data.numfree], ecx
jz .nofree
mov [ebp + editor_data.freeblocks], edx
push edi
.addfree:
add edi, 1000h
add edx, 1000h
mov [edi], edx
loop .addfree
mov [edi], eax
pop edi
.nofree:
sub edi, ebp
mov [ebp + editor_data.last_block], edi
mov ecx, [EditDataSize]
shl ecx, 12
mov [ecx + ebp + edit_block_header.prev], eax
mov [ebp + editor_data.curline], eax
mov [ebp + editor_data.curcol], eax
mov [ebp + editor_data.cursor_x], eax
inc eax
mov [ebp + editor_data.cursor_y], eax
mov eax, [EditBlockStart]
;mov [ebp + editor_data.curpos_offs], eax
mov [ebp + editor_data.linedata_start + editor_line.offs], ax
mov [ebp + editor_data.cur_offs], eax
mov ecx, [ebp + editor_data.first_block]
cmp [ecx + edit_block_header.limit], eax
setz cl
movzx ecx, cl
dec ecx
mov [ebp + editor_data.cur_delta], ecx
call editor_init_lines
editor_OnRedraw:
mov eax, [ebp + editor_data.cursor_x]
mov [cursor_x], eax
mov eax, [ebp + editor_data.cursor_y]
mov [cursor_y], eax
test [ebp + editor_data.flags], 10h
jz @f
mov [cursor_size], cursor_big_size
@@:
call editor_test_cursor_x
call editor_test_cursor_y
call editor_set_keybar
call editor_draw_text
ret
editor_save:
cmp [ebp + editor_data.hPlugin], 0
jz .native
push aCannotSaveToPlugin
mov eax, esp
push ContinueBtn
push 1
push eax
push 1
call SayErr
pop eax
ret
.native:
call editor_calc_filesize
mov ebx, writeinfo
mov [ebx+4], eax
xor eax, eax
mov [ebx+8], eax
mov [ebx+12], eax
mov [ebx+16], eax
lea eax, [ebp + editor_data.filename]
mov [ebx+21], eax
.setsize_retry:
mov byte [ebx], 4
push 70
pop eax
push ebx
int 0x40
pop ebx
mov byte [ebx], 3
test eax, eax
jz .sizeok
push dword [ebx+21]
push aCannotWriteFile
call get_error_msg
push eax
mov eax, esp
push RetryOrCancelBtn
push 2
push eax
push 3
call SayErr
add esp, 12
test eax, eax
jz .setsize_retry
.ret:
ret
.sizeok:
and dword [ebx+4], 0
mov esi, [ebp + editor_data.first_block]
add esi, ebp
mov ebx, [EditBlockStart]
call editor_normalize_offs
jnc .writeok
lea edi, [ebp + editor_data.buf]
.loop:
mov ecx, 16384
call editor_get_data
test eax, eax
jz .done
push ebx
mov ebx, writeinfo
mov [ebx+12], eax
mov [ebx+16], edi
.write_retry:
push 70
pop eax
push ebx
int 0x40
pop ebx
test eax, eax
jz .writeok
push dword [ebx+21]
push aCannotWriteFile
call get_error_msg
push eax
mov eax, esp
push RetryOrCancelBtn
push 2
push eax
push 3
call SayErr
add esp, 12
test eax, eax
jz .write_retry
ret
.writeok:
mov eax, [ebx+12]
add [ebx+4], eax
adc dword [ebx+8], 0
pop ebx
jmp .loop
.done:
and [ebp + editor_data.flags], not 0x80
ret
editor_calc_filesize:
xor eax, eax
push esi
mov esi, [ebp + editor_data.first_block]
@@:
add esi, ebp
add eax, [esi + edit_block_header.limit]
sub eax, [EditBlockStart]
mov esi, [esi + edit_block_header.next]
test esi, esi
jnz @b
pop ebx
ret
editor_get_data:
push edi
test esi, esi
jz .ret
.loop:
mov edx, [esi + edit_block_header.limit]
sub edx, ebx
push ecx
cmp ecx, edx
jb @f
mov ecx, edx
@@:
push esi
add esi, ebx
add ebx, ecx
add eax, ecx
rep movsb
pop esi
pop ecx
sub ecx, edx
jb .ret
mov esi, [esi + edit_block_header.next]
mov ebx, [EditBlockStart]
test esi, esi
jz .ret
add esi, ebp
jmp .loop
.ret:
mov eax, edi
pop edi
sub eax, edi
ret
editor_get_pos:
;mov esi, [ebp + editor_data.curpos_block]
;mov ebx, [ebp + editor_data.curpos_offs]
mov esi, [ebp + editor_data.linedata_start + editor_line.block]
sub esi, ebp
movzx ebx, [ebp + editor_data.linedata_start + editor_line.offs]
@@:
test esi, esi
jz @f
add esi, ebp
cmp ebx, [esi + edit_block_header.limit]
jb @f
mov esi, [esi + edit_block_header.next]
mov ebx, [EditBlockStart]
jmp @b
@@:
ret
editor_curline_start:
mov edx, [EditPlugInfo]
add edx, editor_line.plugdata
mov eax, [ebp + editor_data.cursor_y]
dec eax
imul eax, edx
lea edi, [ebp + eax + editor_data.linedata_start]
mov esi, [edi + editor_line.block]
movzx ebx, [edi + editor_line.offs]
ret
editor_step_forward:
; in: esi = block (must be nonzero), ebx = offset in block
; out: esi = block (zero iff EOF reached), ebx = offset in block
; out: CF=1 iff EOF NOT reached
inc ebx
editor_normalize_offs:
cmp ebx, [esi + edit_block_header.limit]
jb @f
mov esi, [esi + edit_block_header.next]
mov ebx, [EditBlockStart]
test esi, esi
jz @f
add esi, ebp
stc
@@:
ret
editor_step_backward:
; in: esi = block (must be nonzero), ebx = offset in block
; out: esi = block (zero iff input was at the beginning), ebx = offset in block
; out: CF=1 iff start of file reached
dec ebx
cmp ebx, [EditBlockStart]
jae @f
mov esi, [esi + edit_block_header.prev]
test esi, esi
stc
jz @f
add esi, ebp
mov ebx, [esi + edit_block_header.limit]
dec ebx
@@:
ret
editor_get_string:
; read string up to the end of line
; in: esi = block, ebx = offset in block
; in: edi = destination, ecx = maximum number of bytes to copy, edx = number of bytes to skip
; out: esi = block, ebx = offset in block
; out: ecx = number of rest bytes (ecx_in - ecx_out = number of copied characters)
mov ah, [edit_normal_color]
cmp ebx, [esi + edit_block_header.limit]
jz .retnp
push 0 ; current position in line
.loop:
test ecx, ecx
jz .ret
mov al, [esi + ebx]
cmp al, 13
jz .ret
cmp al, 10
jz .ret
cmp al, 9
jz .tab
inc dword [esp]
dec edx
jns .4
xor edx, edx
stosw
dec ecx
.4:
call editor_step_forward
jc .loop
.ret:
pop edx
.retnp:
ret
.tab:
push eax edx
mov eax, [esp+8]
xor edx, edx
div [editor_tabsize]
sub edx, [editor_tabsize]
neg edx
add [esp+8], edx
sub [esp], edx
pop edx eax
jns .4
mov al, ' '
@@:
stosw
dec ecx
jz .ret
inc edx
jnz @b
jmp .4
editor_find_newline:
; in: esi = block, ebx = offset in block
; out: esi = block, ebx = offset in block, ecx = line length
xor ecx, ecx
test esi, esi
jz .ret0
cmp ebx, [esi + edit_block_header.limit]
jb .1
xor esi, esi
.ret0:
ret
.1:
mov al, [esi + ebx]
inc ecx
call editor_step_forward
cmp al, 13
jz .2
cmp al, 10
jz .2
test esi, esi
jnz .1
.ret1:
mov esi, [ebp + editor_data.last_block]
add esi, ebp
mov ebx, [esi + edit_block_header.limit]
ret
.2:
dec ecx
test esi, esi
jz .ret1
cmp al, 13
jnz .ret
cmp byte [esi + ebx], 10
jnz .ret
call editor_step_forward
jnc .ret1
.ret:
ret
editor_prev_newline:
xor ecx, ecx
test esi, esi
jnz @f
mov esi, [ebp + editor_data.last_block]
add esi, ebp
mov ebx, [esi + edit_block_header.limit]
@@:
call editor_step_backward
jc .ret
mov al, [esi + ebx]
call editor_step_backward
jc .ret
cmp al, 10
jnz .1
cmp byte [esi + ebx], 13
jnz .1
@@:
call editor_step_backward
jc .ret
.1:
inc ecx
mov al, [esi + ebx]
cmp al, 13
jz @f
cmp al, 10
jnz @b
@@:
dec ecx
inc ebx
cmp ebx, [esi + edit_block_header.limit]
jb .ret
mov esi, [esi + edit_block_header.next]
mov ebx, [EditBlockStart]
test esi, esi
jz .ret
add esi, ebp
.ret:
test esi, esi
jnz @f
mov esi, [ebp + editor_data.first_block]
mov ebx, [EditBlockStart]
add esi, ebp
@@:
ret
editor_init_lines:
call editor_get_pos
test esi, esi
jnz @f
mov esi, [ebp + editor_data.last_block]
add esi, ebp
mov ebx, [esi + edit_block_header.limit]
@@:
mov ecx, max_height
lea edi, [ebp + editor_data.linedata_start]
.1:
mov eax, esi
stosd ; editor_line.block
mov eax, ebx
stosw ; editor_line.offs
push ecx
call editor_find_newline
;mov eax, ecx
;stosd ; editor_line.length
xor eax, eax
mov ecx, [EditPlugInfo]
rep stosb
pop ecx
loop .1
ret
editor_draw_status:
lea edi, [ebp + editor_data.buf]
mov ah, [edit_status_color]
mov ecx, [cur_width]
sub ecx, 56
cmp ecx, 25
jge @f
push 25
pop ecx
@@:
call viewedit_draw_filename
inc ecx
rep stosw
test [ebp + editor_data.flags], 80h
jz @f
mov al, '*'
@@:
stosw
mov al, ' '
test [ebp + editor_data.flags], 40h
jz @f
mov al, '-'
@@:
stosw
mov al, ' '
test [ebp + editor_data.flags], 20h
jz @f
mov al, '"'
@@:
stosw
mov al, ' '
mov cl, 10
rep stosw
movzx esi, [ebp+editor_data.encoding]
lea esi, [encodings.names+esi*8]
push edi esi
dec edi
dec edi
std
add esi, 8
@@:
dec esi
cmp byte [esi], ' '
jz @b
@@:
lodsb
stosw
cmp esi, [esp]
jae @b
cld
pop esi edi
mov esi, aLine
mov cl, 8
@@:
lodsb
stosw
loop @b
mov cl, 13
mov al, ' '
rep stosw
std
push edi
dec edi
dec edi
push eax
mov eax, [ebp + editor_data.numlines]
mov cl, 10
@@:
xor edx, edx
div ecx
xchg eax, edx
add al, '0'
mov ah, [edit_status_color]
stosw
xchg eax, edx
test eax, eax
jnz @b
mov al, '/'
mov ah, [edit_status_color]
stosw
mov eax, [ebp + editor_data.curline]
add eax, [ebp + editor_data.cursor_y]
@@:
xor edx, edx
div ecx
xchg eax, edx
add al, '0'
mov ah, [edit_status_color]
stosw
xchg eax, edx
test eax, eax
jnz @b
pop eax
stosw
cld
pop edi
mov ah, [edit_status_color]
mov esi, aCol
mov cl, 7
@@:
lodsb
stosw
loop @b
mov eax, [ebp + editor_data.curcol]
add eax, [ebp + editor_data.cursor_x]
inc eax
mov cl, 10
push -'0'
@@:
xor edx, edx
div ecx
push edx
test eax, eax
jnz @b
@@:
pop eax
mov ah, [edit_status_color]
add al, '0'
jz @f
stosw
jmp @b
@@:
mov al, ' '
mov cl, 13
rep stosw
xor eax, eax
xor edx, edx
call get_console_ptr
lea esi, [ebp + editor_data.buf]
mov ecx, [cur_width]
shr ecx, 1
rep movsd
adc ecx, ecx
rep movsw
cmp [ebp + editor_data.cur_delta], -1
jnz .a
mov al, ' '
mov byte [edi-4*2], al
mov byte [edi-3*2], al
mov byte [edi-2*2], al
mov byte [edi-1*2], al
mov eax, [ebp + editor_data.cur_block]
add eax, ebp
add eax, [ebp + editor_data.cur_offs]
movzx eax, byte [eax]
mov cl, 100
;xor edx, edx ; edx=0 already
div ecx
test al, al
jz @f
add al, '0'
mov [edi-3*2], al
@@:
xchg eax, edx
aam
test ah, ah
jnz .b
cmp byte [edi-3*2], ' '
jz @f
.b:
add ah, '0'
mov [edi-2*2], ah
@@:
add al, '0'
mov [edi-1*2], al
.a:
ret
editor_draw_line:
push ecx
mov ecx, [cur_width]
test esi, esi
jz .2
lea edi, [ebp + editor_data.buf]
push edx edi
mov edx, [ebp + editor_data.curcol]
call editor_get_string
mov al, ' '
rep stosw
pop esi edx
xor eax, eax
call get_console_ptr
mov ecx, [cur_width]
shr ecx, 1
rep movsd
adc ecx, ecx
rep movsw
pop ecx
ret
.2:
xor eax, eax
call get_console_ptr
mov al, ' '
mov ah, [edit_normal_color]
rep stosw
pop ecx
ret
editor_draw_text:
call editor_draw_status
push 1
pop edx
lea ecx, [ebp + editor_data.linedata_start]
.1:
mov esi, [ecx + editor_line.block]
movzx ebx, [ecx + editor_line.offs]
add ecx, editor_line.plugdata
add ecx, [EditPlugInfo]
call editor_draw_line
inc edx
mov eax, [cur_height]
dec eax
cmp edx, eax
jb .1
jmp draw_image
editor_set_keybar:
mov eax, keybar_editor
movzx esi, [ebp+editor_data.encoding]
dec esi
jz @f
push 1
pop esi
@@:
lea esi, [encodings.names+esi*8]
lea edi, [eax+keybar_cp2-keybar_editor]
movsd
movsw
jmp draw_keybar
editor_up_scroll:
push ecx
sub [ebp + editor_data.curline], ecx
mov edx, [EditPlugInfo]
add edx, editor_line.plugdata
imul eax, edx, max_height
imul ecx, edx
sub ecx, eax
neg ecx
lea esi, [ebp + ecx + editor_data.linedata_start - 4]
lea edi, [ebp + eax + editor_data.linedata_start - 4]
shr ecx, 2
std
rep movsd
cld
jnc @f
mov cx, [esi+2]
mov [edi+2], cx
sub edi, 2
@@:
pop ecx
add edi, 4
movzx ebx, [edi + editor_line.offs]
mov esi, [edi + editor_line.block]
@@:
push ecx
call editor_prev_newline
sub edi, edx
push edi
mov eax, esi
stosd ; editor_line.offs
mov eax, ebx
stosw ; editor_line.block
;mov eax, ecx
;stosd ; editor_line.length
mov ecx, [EditPlugInfo]
xor eax, eax
rep stosb
pop edi
pop ecx
loop @b
; fall through to editor_update_cur
editor_update_cur:
mov ecx, [ebp + editor_data.cursor_x]
add ecx, [ebp + editor_data.curcol]
call editor_curline_start
xor edx, edx ; current position in the line
cmp ebx, [esi + edit_block_header.limit]
jz .notfound
.scan:
mov al, [esi+ebx]
cmp al, 13
jz .notfound
cmp al, 10
jz .notfound
test ecx, ecx
jz .found
cmp al, 9
jz .tab
inc edx
dec ecx
call editor_step_forward
jc .scan
.notfound:
test esi, esi
jnz @f
mov esi, [ebp + editor_data.last_block]
add esi, ebp
mov ebx, [esi + edit_block_header.limit]
@@:
mov [ebp + editor_data.cur_delta], ecx
xor eax, eax
jmp .reta
.found:
xor eax, eax
.founda:
or [ebp + editor_data.cur_delta], -1
.reta:
sub esi, ebp
mov [ebp + editor_data.cur_block], esi
mov [ebp + editor_data.cur_offs], ebx
ret
.tab:
push edx
mov eax, edx
xor edx, edx
div [editor_tabsize]
sub edx, [editor_tabsize]
neg edx
add [esp], edx
cmp ecx, edx
jb .curintab
sub ecx, edx
pop edx
call editor_step_forward
jnc .notfound
test ecx, ecx
jz .found
jmp .scan
.curintab:
sub [esp], edx
pop edx
cmp edx, [ebp + editor_data.curcol]
setc al
jae @f
mov [ebp + editor_data.curcol], edx
@@:
sub edx, [ebp + editor_data.curcol]
mov [ebp + editor_data.cursor_x], edx
mov [cursor_x], edx
jmp .founda
editor_down_scroll:
push ecx
lea edi, [ebp + editor_data.linedata_start]
mov edx, [EditPlugInfo]
add edx, editor_line.plugdata
imul ecx, edx
lea esi, [edi + ecx]
imul eax, edx, max_height
sub eax, ecx
mov ecx, eax
shr ecx, 2
rep movsd
adc ecx, ecx
rep movsw
@@:
mov esi, edi
sub esi, edx
movzx ebx, [esi + editor_line.offs]
mov esi, [esi + editor_line.block]
pop ecx
jecxz .ret
@@:
push ecx
call editor_find_newline
mov eax, esi
stosd ; editor_line.block
mov eax, ebx
stosw ; editor_line.offs
;mov eax, ecx
;stosd ; editor_line.length
mov ecx, [EditPlugInfo]
xor eax, eax
rep stosb
pop ecx
loop @b
.ret:
ret
editor_end_scroll:
call editor_curline_start
; calculate visible length of the line (it differs from the real length if tabulations are present)
xor ecx, ecx
cmp ebx, [esi + edit_block_header.limit]
jz .calcdone
.calcloop:
mov al, [esi+ebx]
cmp al, 10
jz .calcdone
cmp al, 13
jz .calcdone
cmp al, 9
jz .calctab
inc ecx
.calcnext:
call editor_step_forward
jc .calcloop
jmp .calcdone
.calctab:
mov eax, ecx
xor edx, edx
div [editor_tabsize]
sub edx, [editor_tabsize]
sub ecx, edx
jmp .calcnext
.calcdone:
test esi, esi
jnz @f
mov esi, [ebp + editor_data.last_block]
add esi, ebp
mov ebx, [esi + edit_block_header.limit]
@@:
sub esi, ebp
mov [ebp + editor_data.cur_block], esi
mov [ebp + editor_data.cur_offs], ebx
and [ebp + editor_data.cur_delta], 0
; ecx = number of symbols in the line
; calculate new position of view range
mov eax, [ebp + editor_data.curcol]
cmp ecx, eax
jb .toleft
add eax, [cur_width]
cmp ecx, eax
jae .toright
sub ecx, [ebp + editor_data.curcol]
mov [ebp + editor_data.cursor_x], ecx
mov [cursor_x], ecx
ret
.toleft:
mov [ebp + editor_data.curcol], ecx
and [ebp + editor_data.cursor_x], 0
and [cursor_x], 0
stc
ret
.toright:
mov eax, [cur_width]
dec eax
sub ecx, eax
mov [ebp + editor_data.curcol], ecx
mov [ebp + editor_data.cursor_x], eax
mov [cursor_x], eax
stc
ret
editor_move_linestart:
; in: esi = block, ebx = start offset, ecx = delta
lea edi, [ebp + editor_data.linedata_start]
mov edx, max_height
.0:
cmp [edi + editor_line.block], esi
jnz .1
movzx eax, [edi + editor_line.offs]
cmp eax, ebx
ja .2
; push eax
; add eax, [edi + editor_line.length]
; cmp eax, ebx
; jb @f
; add [edi + editor_line.length], ecx
;@@:
; pop eax
cmp eax, [esi + edit_block_header.limit]
jb .1
push esi ebx
mov ebx, eax
jmp .3
.2:
push esi ebx
mov ebx, eax
add ebx, ecx
.3:
cmp ebx, [esi + edit_block_header.limit]
jb .4
cmp [esi + edit_block_header.next], 0
jz .4
sub ebx, [esi + edit_block_header.limit]
mov esi, [esi + edit_block_header.next]
add esi, ebp
add ebx, [EditBlockStart]
jmp .3
.4:
mov [edi + editor_line.block], esi
mov [edi + editor_line.offs], bx
pop ebx esi
.1:
add edi, editor_line.plugdata
add edi, [EditPlugInfo]
dec edx
jnz .0
;lea edx, [ebp + editor_data.curpos_block]
;call .5
;add edx, editor_data.cur_block - editor_data.curpos_block
lea edx, [ebp + editor_data.cur_block]
; call .5
; ret
.5:
mov eax, [edx]
add eax, ebp
cmp eax, esi
jnz .6
cmp [edx+4], ebx
jbe @f
add [edx+4], ecx
@@:
mov eax, [edx+4]
sub eax, [esi + edit_block_header.limit]
jb .6
push ecx
mov ecx, [esi + edit_block_header.next]
add ecx, ebp
add eax, [EditBlockStart]
mov [edx], ecx
mov [edx+4], eax
pop ecx
.6:
ret
editor_reserve_symbol:
push 1
pop ecx
editor_reserve_space:
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; in: ecx = number of symbols to add, esi = block, ebx = offset
mov eax, [esi + edit_block_header.limit]
add eax, ecx
cmp eax, 4096
ja .add
mov [esi + edit_block_header.limit], eax
push esi ecx
sub eax, ecx
lea esi, [esi + eax - 1]
lea edi, [esi + ecx]
sub eax, ebx
mov ecx, eax
std
rep movsb
cld
pop ecx esi
call editor_move_linestart
clc
ret
.add:
push ecx
mov eax, [esi + edit_block_header.limit]
sub eax, [EditBlockStart]
add eax, ecx
push eax
xor edx, edx
div [EditBlockSize]
push eax
sub eax, [ebp + editor_data.numfree]
jbe .norealloc
mov edx, [ebp + editor_data.memsize]
push eax edx
add eax, edx
mov ecx, eax
shl ecx, 12
mov edx, ebp
call xpgrealloc
pop edx ecx
test eax, eax
jz .nomem
add [ebp + editor_data.memsize], ecx
sub eax, ebp
add ebp, eax
add esi, eax
push ecx
mov ecx, max_height
lea edi, [ebp + editor_data.linedata_start]
@@:
add [edi + editor_line.block], eax
add edi, editor_line.plugdata
add edi, [EditPlugInfo]
loop @b
pop ecx
shl edx, 12
add [ebp + editor_data.numfree], ecx
lea edi, [edx + ebp]
mov eax, [ebp + editor_data.freeblocks]
mov [ebp + editor_data.freeblocks], edx
@@:
add edx, 1000h
mov [edi], edx
add edi, 1000h
loop @b
mov [edi-1000h], eax
.norealloc:
pop edx
push [esi + edit_block_header.next]
push esi
sub [ebp + editor_data.numfree], edx
mov edi, [ebp + editor_data.freeblocks]
@@:
mov [esi + edit_block_header.next], edi
add edi, ebp
push edi
push dword [edi]
stosd ; edit_block_header.next - will be filled later
mov eax, esi
sub eax, ebp
stosd ; edit_block_header.prev
mov eax, 4096 - edit.RESERVE_IN_BLOCK
stosd ; edit_block_header.limit
mov eax, [EditBlockSize]
sub [esp+16], eax
xor eax, eax
mov ecx, [EditPlugInfo]
rep stosb
pop edi
pop esi
dec edx
jnz @b
mov [ebp + editor_data.freeblocks], edi
mov edi, esi
pop esi
pop [edi + edit_block_header.next]
pop ecx
add ecx, [EditBlockSize]
mov edx, ecx
shr edx, 1;2
mov eax, ecx
sub eax, edx
cmp eax, [EditBlockSize]
jb @f
mov eax, [EditBlockSize]
mov edx, ecx
sub edx, eax
@@:
add eax, [EditBlockStart]
add edx, [EditBlockStart]
mov ecx, [esi + edit_block_header.limit]
mov [esi + edit_block_header.limit], eax
mov [edi + edit_block_header.limit], edx
sub ecx, ebx
push ecx
push esi edi ecx
add esi, ecx
add esi, ebx
push edx
sub edx, [EditBlockStart]
cmp ecx, edx
jb @f
mov ecx, edx
@@:
pop edx
sub [esp], ecx
add edi, edx
sub esi, ecx
sub edi, ecx
rep movsb
pop ecx edi esi
push esi edi
lea edi, [esi + eax - 1]
add esi, ebx
lea esi, [esi + ecx - 1]
std
rep movsb
cld
pop edi esi
pop ecx
mov ecx, ebx
sub ecx, eax
jb @f
push esi edi
add esi, eax
add edi, [EditBlockStart]
rep movsb
pop edi esi
@@:
push esi edi
sub esi, ebp
sub edi, ebp
cmp [ebp + editor_data.last_block], esi
jnz @f
mov [ebp + editor_data.last_block], edi
@@:
pop edi esi
pop ecx
call editor_move_linestart
cmp ebx, [esi + edit_block_header.limit]
jb @f
sub ebx, [esi + edit_block_header.limit]
mov esi, [esi + edit_block_header.next]
add esi, ebp
add ebx, [EditBlockStart]
@@:
clc
ret
.nomem:
pop eax
pop ecx
pop ecx
add esi, ebp
stc
ret
editor_delete_symbol:
push 1
pop ecx
editor_delete_space:
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ecx <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> esi:ebx
; ecx, esi, ebx <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
mov eax, [esi + edit_block_header.limit]
sub eax, ebx
cmp eax, ecx
jb .more1
push esi
sub [esi + edit_block_header.limit], ecx
sub eax, ecx
lea edi, [esi+ebx]
lea esi, [edi+ecx]
mov ecx, eax
rep movsb
pop esi
.done:
call .collapse_prev
call .collapse_next
call editor_init_lines
jmp editor_update_cur
.more1:
mov [esi + edit_block_header.limit], ebx
sub ecx, eax
@@:
mov esi, [esi + edit_block_header.next]
add esi, ebp
mov eax, [esi + edit_block_header.limit]
sub eax, [EditBlockStart]
sub ecx, eax
jb @f
call .delete_block
jmp @b
@@:
add ecx, eax
push esi
mov eax, [esi + edit_block_header.limit]
sub [esi + edit_block_header.limit], ecx
add eax, esi
add esi, [EditBlockStart]
mov edi, esi
add esi, ecx
sub eax, esi
mov ecx, esi
rep movsb
pop esi
call .collapse_next
mov esi, [esi + edit_block_header.prev]
add esi, ebp
jmp .done
.delete_block:
mov eax, [esi + edit_block_header.next]
mov edx, [esi + edit_block_header.prev]
test eax, eax
jz .dbfirst
mov [eax + ebp + edit_block_header.prev], edx
jmp @f
.dbfirst:
mov [ebp + editor_data.first_block], edx
@@:
test edx, edx
jz .dblast
mov [edx + ebp + edit_block_header.next], eax
jmp @f
.dblast:
mov [ebp + editor_data.last_block], eax
@@:
mov eax, [ebp + editor_data.freeblocks]
mov [esi], eax
sub esi, ebp
mov [ebp + editor_data.freeblocks], esi
inc [ebp + editor_data.numfree]
ret
.collapse_prev:
mov eax, [esi + edit_block_header.prev]
test eax, eax
jz .cpno
add eax, ebp
mov edx, [esi + edit_block_header.limit]
sub edx, [EditBlockStart]
add edx, [eax + edit_block_header.limit]
cmp edx, 4096 - edit.RESERVE_IN_BLOCK
ja .cpno
mov edi, eax
.collapse: ; (edi) + (esi) -> (edi)
push edi
push esi
mov ecx, [esi + edit_block_header.limit]
sub ecx, [EditBlockStart]
add esi, [EditBlockStart]
mov eax, [edi + edit_block_header.limit]
add [edi + edit_block_header.limit], ecx
add edi, eax
rep movsb
pop esi
call .delete_block
pop esi
.cpno:
ret
.collapse_next:
mov eax, [esi + edit_block_header.next]
test eax, eax
jz .cpno
add eax, ebp
mov edx, [esi + edit_block_header.limit]
sub edx, [EditBlockStart]
add edx, [eax + edit_block_header.limit]
cmp edx, 4096 - edit.RESERVE_IN_BLOCK
ja .cpno
mov edi, esi
mov esi, eax
jmp .collapse
editor_OnKey:
test al, 80h
jnz .ret
test [ebp + editor_data.flags], 20h
jnz .symbol
mov esi, editor_ctrlkeys
call process_ctrl_keys
jnc .ret
.symbol:
and [ebp + editor_data.flags], not 20h
test [ebp + editor_data.flags], 40h
jnz .ret
or [ebp + editor_data.flags], 80h
movzx eax, al
call get_ascii_char
mov esi, [ebp + editor_data.cur_block]
add esi, ebp
mov ebx, [ebp + editor_data.cur_offs]
cmp al, 10
jz .insert_newline
cmp al, 13
jz .insert_newline
cmp [ebp + editor_data.cur_delta], -1
jnz .insert_after_eol
test [ebp + editor_data.flags], 10h
jnz .replace_symbol
push eax
call editor_reserve_symbol
pop eax
jc .ret
.replace_symbol:
cmp ebx, [esi + edit_block_header.limit]
jnz @f
mov esi, [esi + edit_block_header.next]
add esi, ebp
mov ebx, [EditBlockStart]
@@:
mov [esi + ebx], al
.symb_inserted:
call .redraw_curline
jmp .right
.redraw_curline:
call editor_curline_start
mov edx, [cursor_y]
call editor_draw_line
.ret:
ret
.insert_after_eol:
mov ecx, [ebp + editor_data.cur_delta]
inc ecx
push eax
call editor_reserve_space
pop eax
jc .ret
push eax
mov edx, ecx
.2:
mov ecx, [esi + edit_block_header.limit]
sub ecx, ebx
lea edi, [esi + ebx]
cmp ecx, edx
jb @f
mov ecx, edx
@@:
add ebx, ecx
sub edx, ecx
mov al, ' '
rep stosb
jz @f
mov esi, [esi + edit_block_header.next]
add esi, ebp
mov ebx, [EditBlockStart]
jmp .2
@@:
pop eax
mov [edi-1], al
dec ebx
sub esi, ebp
mov [ebp + editor_data.cur_block], esi
mov [ebp + editor_data.cur_offs], ebx
or [ebp + editor_data.cur_delta], -1
jmp .symb_inserted
.insert_newline:
push 1
pop ecx
cmp [ebp + editor_data.eol], 2
adc ecx, 0
call editor_reserve_space
jc .ret
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <EFBFBD><EFBFBD>-<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
; <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> Unix-<EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD> Mac-<EFBFBD><EFBFBD>;
; <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> Mac-<EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD> Unix-<EFBFBD><EFBFBD>.
; <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>.
mov al, [ebp + editor_data.eol]
cmp al, edit.eol_dos
jz .insert_eol_dos
cmp al, edit.eol_mac
jz .insert_eol_mac
mov al, 10 ; Unix-style for end-of-line
push esi ebx
call editor_step_backward
jc @f
cmp byte [esi+ebx], 13
jnz @f
mov al, 13 ; force Mac-style to avoid collapse
@@:
pop ebx esi
mov [esi+ebx], al
jmp .eol_correct
.insert_eol_mac:
mov al, 13 ; Mac-style for end-of-line
push esi ebx
call editor_step_forward
jnc @f
cmp byte [esi+ebx], 10
jnz @f
mov al, 10 ; force Unix-style to avoid collapse
@@:
pop ebx esi
mov [esi+ebx], al
jmp .eol_correct
.insert_eol_dos:
mov byte [esi+ebx], 13
call editor_step_forward
mov byte [esi+ebx], 10
.eol_correct:
call editor_step_forward
test esi, esi
jnz @f
mov esi, [ebp + editor_data.last_block]
add esi, ebp
mov ebx, [esi + edit_block_header.limit]
@@:
and [ebp + editor_data.cur_delta], 0
cmp ebx, [esi + edit_block_header.limit]
jz @f
mov al, [esi+ebx]
cmp al, 10
jz @f
cmp al, 13
jz @f
dec [ebp + editor_data.cur_delta]
@@:
; <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>, <EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>
mov edi, [ebp + editor_data.cursor_y]
mov ecx, max_height-1
sub ecx, edi
dec edi
mov eax, [EditPlugInfo]
add eax, editor_line.plugdata
imul edi, eax, max_height
imul ecx, eax
lea edi, [ebp + edi + editor_data.linedata_start - 2]
push esi
mov esi, edi
sub esi, eax
shr ecx, 1
std
rep movsw
cld
pop esi
add edi, 2
sub edi, eax
push esi
mov esi, edi
sub esi, eax
pop eax
stosd ; editor_line.block
sub eax, ebp
mov [ebp + editor_data.cur_block], eax
mov eax, ebx
stosw ; editor_line.offs
mov [ebp + editor_data.cur_offs], eax
;mov eax, ecx
;stosd ; editor_line.length
mov ecx, [EditPlugInfo]
xor eax, eax
rep stosb
; <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
inc [ebp + editor_data.numlines]
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>
mov [ebp + editor_data.cursor_x], eax
mov [ebp + editor_data.curcol], eax
mov [cursor_x], eax
; <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
mov eax, [ebp + editor_data.cursor_y]
inc eax
mov edx, [cur_height]
dec edx
cmp eax, edx
jae .down_scroll
mov [ebp + editor_data.cursor_y], eax
mov [cursor_y], eax
jmp editor_draw_text
.exit_confirm:
test [ebp + editor_data.flags], 80h
jz .exit
push aFileModified
mov eax, esp
push EditorExitBtn
push 3
push eax
push 1
push aEditorTitle
call SayErrTitle
pop ecx
test eax, eax
jz .save
dec eax
jz .exit
ret
.exit_save:
test [ebp + editor_data.flags], 80h
jz .exit
.save:
call editor_save
.exit:
call editor_OnExit
jmp delete_active_screen
.f2:
call editor_save
jmp .redraw_status
.up_scroll:
cmp [ebp + editor_data.curline], 0
jz .ret
push 1
pop ecx
call editor_up_scroll
jmp editor_draw_text
.up:
mov eax, [ebp + editor_data.cursor_y]
dec eax
jz .up_scroll
.set_cursor_y:
mov [ebp + editor_data.cursor_y], eax
mov [cursor_y], eax
call editor_update_cur
test al, al
jnz editor_draw_text
.redraw_status:
call editor_draw_status
jmp draw_image
.down:
mov eax, [ebp + editor_data.cursor_y]
inc eax
push eax
add eax, [ebp + editor_data.curline]
cmp eax, [ebp + editor_data.numlines]
pop eax
ja .ret
mov edx, [cur_height]
dec edx
cmp eax, edx
jnz .set_cursor_y
.down_scroll:
inc [ebp + editor_data.curline]
lea edi, [ebp + editor_data.linedata_start]
mov eax, [EditPlugInfo]
add eax, editor_line.plugdata
lea esi, [edi + eax]
imul ecx, eax, max_height-1
shr ecx, 2
rep movsd
adc ecx, ecx
rep movsw
sub esi, eax
sub esi, eax
movzx ebx, [esi + editor_line.offs]
mov esi, [esi + editor_line.block]
call editor_find_newline
mov eax, esi
stosd ; editor_line.block
mov eax, ebx
stosw ; editor_line.offs
;mov eax, ecx
;stosd ; editor_line.length
mov ecx, [EditPlugInfo]
xor eax, eax
rep stosb
jmp .ret2
.pgup:
mov ecx, [cur_height]
sub ecx, 3
mov edx, [ebp + editor_data.curline]
mov eax, edx
push edx
sub edx, ecx
jnc @f
xor edx, edx
@@:
mov [ebp + editor_data.curline], edx
add eax, [ebp + editor_data.cursor_y]
dec eax
sub eax, ecx
jnc @f
xor eax, eax
@@:
sub eax, edx
inc eax
mov [ebp + editor_data.cursor_y], eax
mov [cursor_y], eax
pop ecx
sub ecx, edx
push ecx
mov edx, [EditPlugInfo]
add edx, editor_line.plugdata
imul ecx, edx
imul eax, edx, max_height
lea edi, [ebp + editor_data.linedata_start + eax - 2]
mov esi, edi
sub esi, ecx
sub eax, ecx
mov ecx, eax
shr ecx, 1
std
rep movsw
cld
pop ecx
jecxz .ret2
inc edi
inc edi
mov esi, [edi + editor_line.block]
movzx ebx, [edi + editor_line.offs]
@@:
push ecx
call editor_prev_newline
sub edi, edx
push edi
mov eax, esi
stosd ; editor_line.block
mov eax, ebx
stosw ; editor_line.offs
;mov eax, ecx
;stosd ; editor_line.length
mov ecx, [EditPlugInfo]
xor eax, eax
rep stosb
pop edi
pop ecx
loop @b
.ret2:
call editor_update_cur
jmp editor_draw_text
.pgdn:
mov edx, [cur_height]
sub edx, 2
mov ecx, [ebp + editor_data.curline]
push ecx
lea ecx, [edx + ecx - 1]
mov eax, [ebp + editor_data.numlines]
sub eax, edx
jnc @f
xor eax, eax
@@:
cmp ecx, eax
jb @f
mov ecx, eax
@@:
mov [ebp + editor_data.curline], ecx
pop eax
push eax
add eax, [ebp + editor_data.cursor_y]
lea eax, [eax + edx - 1]
cmp eax, [ebp + editor_data.numlines]
jb @f
mov eax, [ebp + editor_data.numlines]
@@:
sub eax, ecx
mov [ebp + editor_data.cursor_y], eax
mov [cursor_y], eax
pop edx
sub ecx, edx
call editor_down_scroll
jmp .ret2
.left:
call editor_cursor_left
jnc .redraw_status
jmp editor_draw_text
.ret3:
ret
.right:
cmp [ebp + editor_data.cur_delta], -1
jz .right_in_text
cmp [ebp + editor_data.curcol], 0x80000000 - 0x1000
jae .ret3
inc [ebp + editor_data.cur_delta]
push 1
pop edx
jmp .right_char
.right_in_text:
mov esi, [ebp + editor_data.cur_block]
add esi, ebp
mov ebx, [ebp + editor_data.cur_offs]
mov al, [esi + ebx]
push eax
call editor_step_forward
test esi, esi
jz .right_eol0
mov al, [esi + ebx]
cmp al, 10
jz .right_eol
cmp al, 13
jz .right_eol
jmp .right_ok
.right_eol0:
mov esi, [ebp + editor_data.last_block]
add esi, ebp
mov ebx, [esi + edit_block_header.limit]
.right_eol:
inc [ebp + editor_data.cur_delta]
.right_ok:
sub esi, ebp
mov [ebp + editor_data.cur_block], esi
mov [ebp + editor_data.cur_offs], ebx
pop eax
push 1
pop edx
cmp al, 9
jnz .right_char
mov eax, [ebp + editor_data.curcol]
add eax, [ebp + editor_data.cursor_x]
xor edx, edx
div [editor_tabsize]
sub edx, [editor_tabsize]
neg edx
.right_char:
mov eax, [ebp + editor_data.cursor_x]
add eax, edx
cmp eax, [cur_width]
jb .set_cursor_x
add eax, [ebp + editor_data.curcol]
mov edx, [cur_width]
dec edx
sub eax, edx
mov [ebp + editor_data.cursor_x], edx
mov [cursor_x], edx
mov [ebp + editor_data.curcol], eax
jmp editor_draw_text
.set_cursor_x:
mov [ebp + editor_data.cursor_x], eax
mov [cursor_x], eax
jmp .redraw_status
.home:
call editor_curline_start
and [ebp + editor_data.cur_delta], 0
cmp ebx, [esi + edit_block_header.limit]
jz @f
mov al, [esi+ebx]
cmp al, 10
jz @f
cmp al, 13
jz @f
dec [ebp + editor_data.cur_delta]
@@:
sub esi, ebp
mov [ebp + editor_data.cur_block], esi
mov [ebp + editor_data.cur_offs], ebx
xor eax, eax
mov [ebp + editor_data.cursor_x], eax
mov [cursor_x], eax
xchg eax, [ebp + editor_data.curcol]
test eax, eax
jnz editor_draw_text
jmp .redraw_status
.end:
call editor_end_scroll
jc editor_draw_text
jmp .redraw_status
.ins:
xor [ebp + editor_data.flags], 10h
mov eax, cursor_normal_size
test [ebp + editor_data.flags], 10h
jz @f
mov eax, cursor_big_size
@@:
mov [cursor_size], eax
jmp draw_image
.backspace:
cmp [ebp + editor_data.cur_delta], -1
jz @f
cmp [ebp + editor_data.cur_delta], 0
jnz .left
@@:
test [ebp + editor_data.flags], 40h
jnz .ret3
mov esi, [ebp + editor_data.cur_block]
add esi, ebp
mov ebx, [ebp + editor_data.cur_offs]
call editor_step_backward
jc .ret3
push esi ebx
call editor_cursor_left
pop ebx esi
setc al
push eax
push esi ebx
cmp byte [esi+ebx], 10
jnz @f
call editor_step_backward
jc @f
cmp byte [esi+ebx], 13
jnz @f
pop eax eax
jmp .del_char
@@:
pop ebx esi
jmp .del_char
.del:
test [ebp + editor_data.flags], 40h
jnz .ret3
mov esi, [ebp + editor_data.cur_block]
add esi, ebp
mov ebx, [ebp + editor_data.cur_offs]
call editor_normalize_offs
jnc .ret3
push 0
.del_char:
or [ebp + editor_data.flags], 80h
mov al, [esi+ebx]
push 1
pop ecx
push eax
push esi ebx
cmp al, 13
jnz @f
call editor_step_forward
jnc @f
cmp byte [esi+ebx], 10
jnz @f
inc ecx
@@:
pop ebx esi
call editor_delete_space
pop eax
cmp al, 13
jz @f
cmp al, 10
jz @f
pop eax
test al, al
jnz .del1
call .redraw_curline
jmp .redraw_status
@@:
pop eax
dec [ebp + editor_data.numlines]
call editor_test_cursor_y
.del1:
jmp editor_draw_text
.f7:
call find_in_file_dlg
jz .shift_f7
.f7.ret:
ret
.shift_f7:
; search string SearchString in file starting from current cursor position
mov ebx, SearchString
xor eax, eax
cmp byte [ebx], al
jz .f7.ret
mov esi, tolower_table
test [find_in_file_dlgdata.flags_case], 10h
jz @f
mov esi, identical_table
@@:
test [find_in_file_dlgdata.flags_whole], 10h
setnz al
push eax
push dword [ebp+editor_data.encoding]; always cp866 for now
; needs to be revisited after Unicode support in editor
call search_string_pre
mov esi, [ebp + editor_data.cur_block]
add esi, ebp
mov ebx, [ebp + editor_data.cur_offs]
call editor_normalize_offs
jnc .f7.notfound
xor edi, edi
push ebx esi
push edi
push edi
test [find_in_file_dlgdata.flags_whole], 10h
jnz @f
movzx eax, byte [esi+ebx]
jmp .search_loop_next
@@:
mov edi, edx
.search_loop:
; edx -> FSM, ecx = last state, esi:ebx -> current data,
; edi = current state
; [esp] = row, [esp+4] = delta in lines
; get current symbol
movzx eax, byte [esi+ebx]
; calculate next state
movzx edi, byte [edi+eax]
; done?
cmp edi, ecx
jz .f7.found
.search_loop_next:
; no; proceed to next symbol
add ebx, 1
shl edi, 8
add dword [esp], 1
add edi, edx
cmp ebx, [esi + edit_block_header.limit]
jae .f7.nextblock
.f7.nonextblock:
cmp al, 10
jz .f7.newline
cmp al, 13
jnz .search_loop
cmp byte [esi+ebx], 10
jnz .f7.newline
call editor_step_forward
jnc .f7.notfound_pop
.f7.newline:
mov dword [esp], 0
add dword [esp+4], 1
mov dword [esp+8], esi
mov dword [esp+12], ebx
jmp .search_loop
.f7.nextblock:
call editor_normalize_offs
jc .f7.nonextblock
.f7.notfound_pop:
; last chance - if we are looking for a whole word, EOF is ok for last symbol
test [find_in_file_dlgdata.flags_whole], 10h
jz @f
mov esi, [ebp + editor_data.last_block]
add esi, ebp
mov ebx, [esi + edit_block_header.limit]
movzx edi, byte [edi+' ']
cmp edi, ecx
jz .f7.found
@@:
add esp, 10h
.f7.notfound:
jmp search_failed
.f7.found:
or [ebp + editor_data.cur_delta], -1
sub ebx, ecx
inc ebx
test [find_in_file_dlgdata.flags_whole], 10h
jz @f
inc ebx
@@:
cmp ebx, [EditBlockStart]
jge @f
sub ebx, [EditBlockStart]
mov esi, [esi + edit_block_header.prev]
add esi, ebp
add ebx, [esi + edit_block_header.limit]
jmp @b
@@:
sub esi, ebp
mov [ebp + editor_data.cur_block], esi
add esi, ebp
mov [ebp + editor_data.cur_offs], ebx
push ecx
mov ecx, edx
call pgfree
pop ecx
pop eax
pop edi
; esi:ebx -> last symbol of match, eax = row, edi = delta in lines
pop esi ebx
test [find_in_file_dlgdata.flags_whole], 10h
jz @f
dec ecx
@@:
push ebx esi
sub eax, ecx
lea edx, [eax+1]
mov eax, [ebp + editor_data.curcol]
add eax, [ebp + editor_data.cursor_x]
test edi, edi
jz @f
xor eax, eax
@@:
test edx, edx
jz .f7.foundpos1
.f7.findpos1:
cmp byte [ebx+esi], 9
jz .f7.findpos1.tab
inc eax
call editor_step_forward
dec edx
jnz .f7.findpos1
jmp .f7.foundpos1
.f7.findpos1.tab:
push edx eax
xor edx, edx
div [editor_tabsize]
pop eax
sub edx, [editor_tabsize]
sub eax, edx
call editor_step_forward
pop edx
dec edx
jnz .f7.findpos1
.f7.foundpos1:
pop esi ebx
push eax
cmp eax, [ebp + editor_data.curcol]
jb .f7.scrollleft
sub eax, [ebp + editor_data.curcol]
sub eax, [cur_width]
jb .f7.xset
inc eax
inc edx
add [ebp + editor_data.curcol], eax
jmp .f7.xset
.f7.scrollleft:
inc edx
mov [ebp + editor_data.curcol], eax
.f7.xset:
pop eax
push edx
sub eax, [ebp + editor_data.curcol]
mov [ebp + editor_data.cursor_x], eax
mov [cursor_x], eax
add edi, [ebp + editor_data.cursor_y]
push edi
inc edi
cmp edi, [cur_height]
pop edi
jae .f7.newview
mov [ebp + editor_data.cursor_y], edi
mov [cursor_y], edi
jmp .f7.yset
.f7.newview:
dec edi
mov [ebp + editor_data.linedata_start + editor_line.block], esi
mov [ebp + editor_data.linedata_start + editor_line.offs], bx
add [ebp + editor_data.curline], edi
xor eax, eax
inc eax
mov [ebp + editor_data.cursor_y], eax
mov [cursor_y], eax
call editor_init_lines
call editor_test_cursor_y
inc dword [esp]
.f7.yset:
pop eax
test eax, eax
jz .redraw_status
jmp editor_draw_text
editor_cursor_left:
cmp [ebp + editor_data.cur_delta], -1
jz .in_text
dec [ebp + editor_data.cur_delta]
cmp [ebp + editor_data.cur_delta], -1
jnz .left_cursor
.in_text:
mov esi, [ebp + editor_data.cur_block]
add esi, ebp
mov ebx, [ebp + editor_data.cur_offs]
call editor_step_backward
jc .ret_clc
mov al, [esi + ebx]
cmp al, 13
jz .eol
cmp al, 10
jz .eol2
cmp al, 9
jz .tab
sub esi, ebp
mov [ebp + editor_data.cur_block], esi
mov [ebp + editor_data.cur_offs], ebx
.left_cursor:
mov eax, [ebp + editor_data.cursor_x]
test eax, eax
jz @f
dec eax
.set_cursor_x:
mov [ebp + editor_data.cursor_x], eax
mov [cursor_x], eax
.ret_clc:
clc
ret
@@:
dec [ebp + editor_data.curcol]
jmp .ret_stc
.tab:
mov eax, [ebp + editor_data.cursor_x]
test eax, eax
jz @f
dec eax
mov [ebp + editor_data.cursor_x], eax
mov [cursor_x], eax
call editor_update_cur
test al, al
jz .ret_clc
.ret_stc:
stc
ret
@@:
dec [ebp + editor_data.curcol]
call editor_update_cur
jmp .ret_stc
.eol2:
push esi ebx
call editor_step_backward
jc @f
cmp byte [esi + ebx], 13
jnz @f
pop eax eax
push esi ebx
@@:
pop ebx esi
.eol:
mov eax, [ebp + editor_data.cursor_y]
dec eax
jz .scroll_left_toup
push 0 ; no full redraw
mov [ebp + editor_data.cursor_y], eax
mov [cursor_y], eax
jmp .scroll_left_toend
.scroll_left_toup:
push 1
pop ecx
call editor_up_scroll
push 1 ; full redraw required
.scroll_left_toend:
call editor_end_scroll
pop eax
adc al, 0
jnz .ret_stc
jmp .ret_clc
editor_test_cursor_x:
mov ecx, [cur_width]
dec ecx
mov eax, [ebp + editor_data.cursor_x]
sub eax, ecx
jbe @f
add [ebp + editor_data.curcol], eax
mov [ebp + editor_data.cursor_x], ecx
mov [cursor_x], ecx
@@:
ret
editor_test_cursor_y:
mov ecx, [ebp + editor_data.cursor_y]
mov edx, [cur_height]
dec edx
dec edx
sub ecx, edx
ja .scroll_down
mov ecx, [ebp + editor_data.curline]
add ecx, edx
sub ecx, [ebp + editor_data.numlines]
ja .scroll_up
.clc_ret:
clc
ret
.scroll_down:
add [ebp + editor_data.curline], ecx
sub [ebp + editor_data.cursor_y], ecx
sub [cursor_y], ecx
call editor_down_scroll
stc
ret
.scroll_up:
cmp ecx, [ebp + editor_data.curline]
jb @f
mov ecx, [ebp + editor_data.curline]
@@:
jecxz .clc_ret
add [ebp + editor_data.cursor_y], ecx
add [cursor_y], ecx
call editor_up_scroll
stc
ret
editor_OnExit:
mov edx, [ebp+editor_data.hPlugin]
test edx, edx
jz @f
mov ebx, [ebp+editor_data.hFile]
call close_handle_if_unused
@@:
ret
find_in_file_dlg:
mov ebx, find_in_file_dlgdata
mov eax, [cur_width]
sub eax, 12
mov [ebx + dlgtemplate.width], eax
dec eax
dec eax
mov [ebx - find_in_file_dlgdata + find_in_file_dlgdata.width2], eax
shr eax, 1
dec eax
dec eax
mov [ebx - find_in_file_dlgdata + find_in_file_dlgdata.search_x2], eax
sub eax, aSearchBLength-1
mov [ebx - find_in_file_dlgdata + find_in_file_dlgdata.search_x1], eax
add eax, aSearchBLength+3
mov [ebx - find_in_file_dlgdata + find_in_file_dlgdata.cnl_x1], eax
add eax, aCancelBLength - 1
mov [ebx - find_in_file_dlgdata + find_in_file_dlgdata.cnl_x2], eax
mov byte [ebx - find_in_file_dlgdata + find_in_file_dlgdata.flags0], 0xC
and byte [ebx - find_in_file_dlgdata + find_in_file_dlgdata.flags1], not 4
and byte [ebx - find_in_file_dlgdata + find_in_file_dlgdata.flags2], not 4
and byte [ebx - find_in_file_dlgdata + find_in_file_dlgdata.flags_case], not 4
and byte [ebx - find_in_file_dlgdata + find_in_file_dlgdata.flags_whole], not 4
push ebx
call DialogBox
cmp eax, find_in_file_dlgdata.search_btn
ret