kolibrios/programs/fs/kfar/trunk/editor.inc
IgorA 9f0eae6809 KFar: fix conflict mouse and f3 mode, clean code
git-svn-id: svn://kolibrios.org@8960 a494cfbc-eb01-0410-851d-a64ba20cac60
2021-06-28 20:25:58 +00:00

2573 lines
50 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 + PanelData.files]
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 + PanelData.dir]
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
sub eax, ebp
add ebp, eax
add esi, eax
add [ebp + editor_data.memsize], ecx
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