Initall commit
This commit is contained in:
511
fasmw172/SOURCE/IDE/NAVIGATE.INC
Normal file
511
fasmw172/SOURCE/IDE/NAVIGATE.INC
Normal file
@@ -0,0 +1,511 @@
|
||||
|
||||
; flat editor core
|
||||
; Copyright (c) 1999-2015, Tomasz Grysztar.
|
||||
; All rights reserved.
|
||||
|
||||
find_line:
|
||||
mov esi,[first_line]
|
||||
mov ecx,1
|
||||
mov edx,[window_line_number]
|
||||
cmp eax,edx
|
||||
jae forward_from_window
|
||||
sub edx,eax
|
||||
cmp edx,eax
|
||||
jb backward_from_window
|
||||
jmp find_forward
|
||||
forward_from_window:
|
||||
mov esi,[window_line]
|
||||
mov ecx,edx
|
||||
find_forward:
|
||||
cmp ecx,eax
|
||||
je line_found
|
||||
cmp dword [esi],0
|
||||
je line_found
|
||||
mov ebx,esi
|
||||
forward_skip_line:
|
||||
mov ebx,[ebx]
|
||||
btr ebx,0
|
||||
jc forward_skip_line
|
||||
or ebx,ebx
|
||||
jz line_found
|
||||
mov esi,ebx
|
||||
inc ecx
|
||||
jmp find_forward
|
||||
backward_from_window:
|
||||
mov esi,[window_line]
|
||||
mov ecx,[window_line_number]
|
||||
find_backward:
|
||||
cmp ecx,eax
|
||||
je line_found
|
||||
cmp dword [esi+4],0
|
||||
je line_found
|
||||
mov esi,[esi+4]
|
||||
dec ecx
|
||||
jmp find_backward
|
||||
line_found:
|
||||
retn
|
||||
|
||||
get_caret_segment:
|
||||
mov edx,[caret_position]
|
||||
mov esi,[caret_line]
|
||||
find_segment:
|
||||
cmp edx,SEGMENT_DATA_LENGTH
|
||||
jb segment_found
|
||||
test byte [esi],1
|
||||
jz segment_found
|
||||
mov esi,[esi]
|
||||
dec esi
|
||||
sub edx,SEGMENT_DATA_LENGTH
|
||||
jmp find_segment
|
||||
segment_found:
|
||||
retn
|
||||
|
||||
check_line_length:
|
||||
xor edx,edx
|
||||
mov ebx,esi
|
||||
count_line_segments:
|
||||
test byte [esi],1
|
||||
jz last_line_segment
|
||||
mov esi,[esi]
|
||||
dec esi
|
||||
add edx,SEGMENT_DATA_LENGTH
|
||||
jmp count_line_segments
|
||||
last_line_segment:
|
||||
lea edi,[esi+SEGMENT_LENGTH-1]
|
||||
mov al,20h
|
||||
mov ecx,SEGMENT_DATA_LENGTH
|
||||
std
|
||||
repe scasb
|
||||
cld
|
||||
setne al
|
||||
movzx eax,al
|
||||
add ecx,eax
|
||||
jnz line_segments_ok
|
||||
or edx,edx
|
||||
jz line_segments_ok
|
||||
call store_freed_segment_for_undo
|
||||
mov eax,[esi]
|
||||
mov esi,[esi+4]
|
||||
dec esi
|
||||
call store_segment_for_undo
|
||||
mov [esi],eax
|
||||
sub edx,SEGMENT_DATA_LENGTH
|
||||
jmp last_line_segment
|
||||
line_segments_ok:
|
||||
add ecx,edx
|
||||
mov edx,ecx
|
||||
cmp edx,[ebx+8]
|
||||
je line_length_checked
|
||||
mov esi,ebx
|
||||
call store_segment_for_undo
|
||||
xchg [ebx+8],edx
|
||||
push edx
|
||||
mov eax,[ebx+8]
|
||||
call register_length
|
||||
pop eax
|
||||
call unregister_length
|
||||
line_length_checked:
|
||||
retn
|
||||
register_length:
|
||||
cmp eax,[peak_line_length]
|
||||
jbe peak_length_ok
|
||||
mov [peak_line_length],eax
|
||||
peak_length_ok:
|
||||
or eax,eax
|
||||
jz ignore_zero_length
|
||||
push ebx
|
||||
call find_lengths_segment
|
||||
inc dword [ebx+SEGMENT_HEADER_LENGTH+eax*4]
|
||||
pop ebx
|
||||
ignore_zero_length:
|
||||
retn
|
||||
find_lengths_segment:
|
||||
mov ebx,[lengths_table]
|
||||
try_lengths_segment:
|
||||
cmp eax,SEGMENT_DATA_LENGTH/4
|
||||
jb length_entry_ok
|
||||
sub eax,SEGMENT_DATA_LENGTH/4
|
||||
cmp dword [ebx],0
|
||||
je add_lengths_segment
|
||||
mov ebx,[ebx]
|
||||
jmp try_lengths_segment
|
||||
add_lengths_segment:
|
||||
push eax ecx edi
|
||||
call allocate_segment
|
||||
jc memory_shortage
|
||||
call store_allocated_segment_for_undo
|
||||
mov [ebx],eax
|
||||
mov edi,eax
|
||||
xor eax,eax
|
||||
stosd
|
||||
mov eax,ebx
|
||||
stosd
|
||||
mov eax,[ebx+8]
|
||||
add eax,SEGMENT_DATA_LENGTH/4
|
||||
stosd
|
||||
add edi,SEGMENT_HEADER_LENGTH-12
|
||||
mov ecx,SEGMENT_DATA_LENGTH shr 2
|
||||
xor eax,eax
|
||||
rep stosd
|
||||
lea ebx,[edi-SEGMENT_LENGTH]
|
||||
pop edi ecx eax
|
||||
jmp try_lengths_segment
|
||||
length_entry_ok:
|
||||
retn
|
||||
unregister_length:
|
||||
or eax,eax
|
||||
jz ignore_zero_length
|
||||
push ebx
|
||||
cmp eax,[peak_line_length]
|
||||
je unregister_peak_length
|
||||
call find_lengths_segment
|
||||
dec dword [ebx+SEGMENT_HEADER_LENGTH+eax*4]
|
||||
length_unregistered:
|
||||
pop ebx
|
||||
retn
|
||||
unregister_peak_length:
|
||||
call find_lengths_segment
|
||||
dec dword [ebx+SEGMENT_HEADER_LENGTH+eax*4]
|
||||
jnz length_unregistered
|
||||
find_reduced_peak:
|
||||
or eax,eax
|
||||
jz try_earlier_lengths_segment
|
||||
dec eax
|
||||
cmp dword [ebx+SEGMENT_HEADER_LENGTH+eax*4],0
|
||||
je find_reduced_peak
|
||||
add eax,[ebx+8]
|
||||
mov [peak_line_length],eax
|
||||
jmp length_unregistered
|
||||
try_earlier_lengths_segment:
|
||||
mov ebx,[ebx+4]
|
||||
mov eax,SEGMENT_DATA_LENGTH/4
|
||||
or ebx,ebx
|
||||
jnz find_reduced_peak
|
||||
mov [peak_line_length],ebx
|
||||
jmp length_unregistered
|
||||
|
||||
update_window:
|
||||
mov edx,[window_line_number]
|
||||
cmp edx,1
|
||||
je window_vertical_position_ok
|
||||
add edx,[window_height]
|
||||
dec edx
|
||||
cmp edx,[lines_count]
|
||||
jle window_vertical_position_ok
|
||||
sub edx,[lines_count]
|
||||
window_vertical_correction:
|
||||
mov esi,[window_line]
|
||||
mov esi,[esi+4]
|
||||
or esi,esi
|
||||
jz window_vertical_position_ok
|
||||
mov [window_line],esi
|
||||
dec [window_line_number]
|
||||
dec edx
|
||||
jnz window_vertical_correction
|
||||
window_vertical_position_ok:
|
||||
mov ecx,[peak_line_length]
|
||||
cmp ecx,[caret_position]
|
||||
jae caret_position_ok
|
||||
mov ecx,[caret_position]
|
||||
caret_position_ok:
|
||||
cmp [selection_line],0
|
||||
je selection_position_ok
|
||||
cmp ecx,[selection_position]
|
||||
jae selection_position_ok
|
||||
mov ecx,[selection_position]
|
||||
selection_position_ok:
|
||||
mov eax,[window_width]
|
||||
dec eax
|
||||
cmp ecx,eax
|
||||
jae edit_space_width_ok
|
||||
mov ecx,eax
|
||||
edit_space_width_ok:
|
||||
mov [maximum_position],ecx
|
||||
mov edx,[window_position]
|
||||
or edx,edx
|
||||
jz window_horizontal_position_ok
|
||||
add edx,[window_width]
|
||||
inc ecx
|
||||
cmp edx,ecx
|
||||
jbe window_horizontal_position_ok
|
||||
sub edx,ecx
|
||||
sub [window_position],edx
|
||||
jnc window_horizontal_position_ok
|
||||
mov [window_position],0
|
||||
window_horizontal_position_ok:
|
||||
retn
|
||||
|
||||
let_caret_appear:
|
||||
mov eax,[caret_position]
|
||||
cmp eax,[window_position]
|
||||
jl horizontal_correction
|
||||
mov ecx,[window_width]
|
||||
jecxz last_position_ok
|
||||
dec ecx
|
||||
last_position_ok:
|
||||
add ecx,[window_position]
|
||||
mov eax,[caret_position]
|
||||
sub eax,ecx
|
||||
jbe horizontal_ok
|
||||
add eax,[window_position]
|
||||
horizontal_correction:
|
||||
mov [window_position],eax
|
||||
horizontal_ok:
|
||||
mov esi,[caret_line]
|
||||
mov ecx,[caret_line_number]
|
||||
cmp ecx,[window_line_number]
|
||||
jl vertical_correction
|
||||
mov eax,[window_height]
|
||||
or eax,eax
|
||||
jz vertical_check
|
||||
dec eax
|
||||
vertical_check:
|
||||
neg eax
|
||||
add eax,[caret_line_number]
|
||||
cmp [window_line_number],eax
|
||||
jge vertical_ok
|
||||
mov esi,[window_line]
|
||||
mov ecx,[window_line_number]
|
||||
vertical_find:
|
||||
mov esi,[esi]
|
||||
btr esi,0
|
||||
jc vertical_find
|
||||
inc ecx
|
||||
cmp ecx,eax
|
||||
jl vertical_find
|
||||
vertical_correction:
|
||||
mov [window_line],esi
|
||||
mov [window_line_number],ecx
|
||||
vertical_ok:
|
||||
retn
|
||||
|
||||
move_line_up:
|
||||
mov esi,[caret_line]
|
||||
mov eax,[esi+4]
|
||||
or eax,eax
|
||||
jz cannot_move
|
||||
mov [caret_line],eax
|
||||
dec [caret_line_number]
|
||||
clc
|
||||
retn
|
||||
cannot_move:
|
||||
stc
|
||||
retn
|
||||
|
||||
move_line_down:
|
||||
mov esi,[caret_line]
|
||||
find_next_line:
|
||||
mov eax,[esi]
|
||||
or eax,eax
|
||||
jz cannot_move
|
||||
btr eax,0
|
||||
jnc down_ok
|
||||
mov esi,eax
|
||||
jmp find_next_line
|
||||
down_ok:
|
||||
mov [caret_line],eax
|
||||
inc [caret_line_number]
|
||||
clc
|
||||
retn
|
||||
|
||||
move_page_up:
|
||||
mov eax,[caret_line_number]
|
||||
sub eax,[window_height]
|
||||
ja pgup_caret_ok
|
||||
mov eax,1
|
||||
pgup_caret_ok:
|
||||
call find_line
|
||||
mov [caret_line],esi
|
||||
mov [caret_line_number],ecx
|
||||
mov eax,[window_line_number]
|
||||
sub eax,[window_height]
|
||||
ja pgup_window_ok
|
||||
mov eax,1
|
||||
cmp [window_line_number],eax
|
||||
je moved_ok
|
||||
pgup_window_ok:
|
||||
call find_line
|
||||
mov [window_line],esi
|
||||
mov [window_line_number],ecx
|
||||
retn
|
||||
|
||||
move_page_down:
|
||||
mov eax,[caret_line_number]
|
||||
add eax,[window_height]
|
||||
call find_line
|
||||
mov [caret_line],esi
|
||||
mov [caret_line_number],ecx
|
||||
mov eax,[window_line_number]
|
||||
mov ecx,[window_height]
|
||||
add eax,ecx
|
||||
mov ebx,[lines_count]
|
||||
sub ebx,ecx
|
||||
jbe moved_ok
|
||||
inc ebx
|
||||
cmp eax,ebx
|
||||
jb pgdn_window_ok
|
||||
mov eax,ebx
|
||||
cmp [window_line_number],eax
|
||||
je moved_ok
|
||||
pgdn_window_ok:
|
||||
call find_line
|
||||
mov [window_line],esi
|
||||
mov [window_line_number],ecx
|
||||
moved_ok:
|
||||
retn
|
||||
|
||||
move_to_previous_word:
|
||||
call get_caret_segment
|
||||
mov ecx,[caret_position]
|
||||
sub ecx,edx
|
||||
cmp edx,SEGMENT_DATA_LENGTH
|
||||
jbe find_word_to_the_left
|
||||
mov edx,SEGMENT_DATA_LENGTH
|
||||
find_word_to_the_left:
|
||||
sub edx,1
|
||||
jc word_in_previous_segment
|
||||
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
|
||||
call recognize_character
|
||||
jnc find_word_start
|
||||
jmp find_word_to_the_left
|
||||
word_in_previous_segment:
|
||||
mov eax,[esi+4]
|
||||
or eax,eax
|
||||
jz previous_word_ok
|
||||
mov esi,eax
|
||||
btr esi,0
|
||||
jnc word_in_previous_line
|
||||
mov edx,SEGMENT_DATA_LENGTH
|
||||
sub ecx,edx
|
||||
jmp find_word_to_the_left
|
||||
word_in_previous_line:
|
||||
mov [caret_line],esi
|
||||
dec [caret_line_number]
|
||||
mov edx,SEGMENT_DATA_LENGTH
|
||||
xor ecx,ecx
|
||||
find_last_segment:
|
||||
test byte [esi],1
|
||||
jz find_word_to_the_left
|
||||
mov esi,[esi]
|
||||
dec esi
|
||||
add ecx,SEGMENT_DATA_LENGTH
|
||||
jmp find_last_segment
|
||||
find_word_start:
|
||||
sub edx,1
|
||||
jc word_on_segment_edge
|
||||
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
|
||||
call recognize_character
|
||||
jc previous_word_ok
|
||||
jmp find_word_start
|
||||
word_on_segment_edge:
|
||||
mov esi,[esi+4]
|
||||
btr esi,0
|
||||
jnc previous_word_ok
|
||||
mov edx,SEGMENT_DATA_LENGTH
|
||||
sub ecx,edx
|
||||
jmp find_word_start
|
||||
previous_word_ok:
|
||||
add ecx,edx
|
||||
inc ecx
|
||||
mov [caret_position],ecx
|
||||
retn
|
||||
|
||||
move_to_next_word:
|
||||
mov ecx,[caret_position]
|
||||
sub ecx,edx
|
||||
find_word_end:
|
||||
cmp edx,SEGMENT_DATA_LENGTH
|
||||
jae word_wraps_segment_edge
|
||||
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
|
||||
call recognize_character
|
||||
jc find_word_to_the_right
|
||||
add edx,1
|
||||
jmp find_word_end
|
||||
word_wraps_segment_edge:
|
||||
mov esi,[esi]
|
||||
or esi,esi
|
||||
jz move_to_line_end
|
||||
btr esi,0
|
||||
jnc word_in_next_line
|
||||
add ecx,SEGMENT_DATA_LENGTH
|
||||
sub edx,SEGMENT_DATA_LENGTH
|
||||
jmp find_word_end
|
||||
find_word_to_the_right:
|
||||
cmp edx,SEGMENT_DATA_LENGTH
|
||||
jae word_in_next_segment
|
||||
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
|
||||
call recognize_character
|
||||
jnc next_word_ok
|
||||
add edx,1
|
||||
jmp find_word_to_the_right
|
||||
word_in_next_segment:
|
||||
mov esi,[esi]
|
||||
or esi,esi
|
||||
jz move_to_line_end
|
||||
btr esi,0
|
||||
jnc word_in_next_line
|
||||
add ecx,SEGMENT_DATA_LENGTH
|
||||
sub edx,SEGMENT_DATA_LENGTH
|
||||
jmp find_word_to_the_right
|
||||
word_in_next_line:
|
||||
mov [caret_line],esi
|
||||
inc [caret_line_number]
|
||||
xor ecx,ecx
|
||||
xor edx,edx
|
||||
jmp find_word_to_the_right
|
||||
next_word_ok:
|
||||
add ecx,edx
|
||||
mov [caret_position],ecx
|
||||
retn
|
||||
move_to_line_end:
|
||||
mov esi,[caret_line]
|
||||
mov eax,[esi+8]
|
||||
mov [caret_position],eax
|
||||
retn
|
||||
|
||||
get_word_at_caret:
|
||||
call get_caret_segment
|
||||
mov ebx,[caret_position]
|
||||
sub ebx,edx
|
||||
find_left_edge:
|
||||
or edx,edx
|
||||
jz left_edge_in_previous_segment
|
||||
cmp edx,SEGMENT_DATA_LENGTH
|
||||
ja left_edge_ok
|
||||
mov al,[esi+SEGMENT_HEADER_LENGTH+edx-1]
|
||||
call recognize_character
|
||||
jc left_edge_ok
|
||||
dec edx
|
||||
jmp find_left_edge
|
||||
left_edge_in_previous_segment:
|
||||
mov esi,[esi+4]
|
||||
btr esi,0
|
||||
jnc left_edge_ok
|
||||
mov edx,SEGMENT_DATA_LENGTH
|
||||
sub ebx,edx
|
||||
jmp find_left_edge
|
||||
left_edge_ok:
|
||||
add ebx,edx
|
||||
call get_caret_segment
|
||||
mov ecx,[caret_position]
|
||||
sub ecx,edx
|
||||
find_right_edge:
|
||||
cmp edx,SEGMENT_DATA_LENGTH
|
||||
jae right_edge_in_next_segment
|
||||
mov al,[esi+SEGMENT_HEADER_LENGTH+edx]
|
||||
call recognize_character
|
||||
jc right_edge_ok
|
||||
inc edx
|
||||
jmp find_right_edge
|
||||
right_edge_in_next_segment:
|
||||
mov esi,[esi]
|
||||
btr esi,0
|
||||
jnc right_edge_ok
|
||||
xor edx,edx
|
||||
add ecx,SEGMENT_DATA_LENGTH
|
||||
jmp find_right_edge
|
||||
right_edge_ok:
|
||||
add ecx,edx
|
||||
sub ecx,ebx
|
||||
mov edx,ebx
|
||||
retn
|
||||
Reference in New Issue
Block a user