redaguje:VIM Undo: Dlaczego kursor przeskakuje do niewłaściwej pozycji po cofnięciu "cofania"?
Mam uproszczone funkcje i wyjaśnić pytanie.
Oryginalne pytanie jest nadal dostępne w dalszej części strony.Crossposted na liście vim_dev korespondencji: https://groups.google.com/forum/#!topic/vim_dev/_Rz3uVXbwsQ
Zgłoszone jako błąd do Neovim:
https://github.com/neovim/neovim/issues/6276
Dlaczego kursor umieszczony w różny sposób w dwóch poniższych przykładach :
[PRAWID¸OWE pozycja kursora] Następujący testy wytwarza oczekiwane zmiany podstawienie wynik połączony z poprzedniej zmiany w buforze (dodanie linia 3), pozycja kursor prawidłowo doprowadzony do drugiej linii w buforze .
normal ggiline one is full of aaaa set undolevels=10 " splits the change into separate undo blocks normal Goline two is full of bbbb set undolevels=10 normal Goline three is full of cccc set undolevels=10 undojoin keepjumps %s/aaaa/zzzz/ normal u
[NIEPOPRAWNA pozycja kursora] Następujący testy wytwarza nieoczekiwany wynik: Zmiana Zmiana jest połączona z poprzedniej zmiany w buforze (dodanie linia 4), pozycja kursor nieprawidłowo przywrócić pierwszy linia w buforze (powinna być linią 3).
normal ggiline one is bull of aaaa set undolevels=10 " splits the change into separate undo blocks normal Goline two is full of bbbb set undolevels=10 normal Goline three is full of cccc set undolevels=10 normal Goline four is full of aaaa's again set undolevels=10 undojoin keepjumps %s/aaaa/zzzz/ normal u
oryginalne pytanie
Droga moja VIM jest skonfigurowana, oszczędzając bufor do pliku wyzwala zwyczaj StripTrailingSpaces() funkcja (załączony na końcu pytanie):
autocmd BufWritePre,FileWritePre,FileAppendPre,FilterWritePre <buffer>
\ :keepjumps call UmkaDK#StripTrailingSpaces(0)
Po obejrzeniu Restore the cursor position after undoing text change made by a script, mam pomysł, aby wykluczyć zmiany dokonane przez moich StripTrailingSpaces() funkcja z historii cofania poprzez scalenie rekordu cofnięcia utworzonego przez funkcję na końcu poprzedniej zmiany w buforze.
W ten sposób, po cofnięciu zmian, wygląda na to, że funkcja nie utworzyła w ogóle własnego rekordu cofania.
Aby potwierdzić mój pomysł Użyłem prosty przypadek testowy: tworzenie czystego bufor i wprowadź następujące komendy ręcznie lub zapisać następujący blok jako plik i źródła, poprzez:
vim +"source <saved-filename-here>"
normal ggiline one is full of aaaa
set undolevels=10 " splits the change into separate undo blocks
normal Goline two is full of bbbb
set undolevels=10
normal Goline three is full of cccc
set undolevels=10
undojoin
keepjumps %s/aaaa/zzzz/
normal u
Jak widać, po cofnięciu ostatniej zmiany w buforze, która tworzy trzecią linię, kursor jest poprawnie zwracany do drugiej linii w pliku.
Od kiedy mój test zadziałał, zaimplementowałem prawie identyczne undojoin
w moim StripTrailingSpaces(). Jednak po cofnięciu ostatniej zmiany po uruchomieniu funkcji kursor jest zwracany do najwyższej, najbardziej zmieniającej się w pliku. Często jest to spakowana przestrzeń i jest to pozycja, której zmiana została zmieniona na .
Czy ktoś może pomyśleć, dlaczego tak się stało? Jeszcze lepiej, czy ktoś może zaproponować poprawkę?
function! UmkaDK#StripTrailingSpaces(number_of_allowed_spaces)
" Match all trailing spaces in a file
let l:regex = [
\ '\^\zs\s\{1,\}\$',
\ '\S\s\{' . a:number_of_allowed_spaces . '\}\zs\s\{1,\}\$',
\ ]
" Join trailing spaces regex into a single, non-magic string
let l:regex_str = '\V\(' . join(l:regex, '\|') . '\)'
" Save current window state
let l:[email protected]/
let l:winview = winsaveview()
try
" Append the comming change onto the end of the previous change
" NOTE: Fails if previous change doesn't exist
undojoin
catch
endtry
" Substitute all trailing spaces
if v:version > 704 || v:version == 704 && has('patch155')
execute 'keepjumps keeppatterns %s/' . l:regex_str . '//e'
else
execute 'keepjumps %s/' . l:regex_str . '//e'
call histdel('search', -1)
endif
" Restore current window state
call winrestview(l:winview)
let @/=l:last_search
endfunction
Niestety, ale jaka jest różnica między tymi 75 liniami a ':% s/\ s * $ /'? – steffen
@steffen: Cóż ... jej 74 linii i 2866 znaków dłużej ... ma również opisowe komentarze, zachowuje historię wyszukiwania i ostatni ciąg wyszukiwania, nie zmienia znaków "", '', .' i ''^", nie dodaje nowego rekordu 'jumplist' i' changelist', zachowuje swój widok i pozycję kursora, a * powinien * tworzyć lepsze cofanie. (Chociaż ostatni punkt jest subiektywny i jest powodem, dla którego to pytanie jest tutaj.) – UmkaDK
Pozycja kursora jest pamiętana przed wprowadzeniem zmian, a następnie przywracana po cofnięciu zmian. –