Почему скрипт VIM выполняет команды дважды: возможные причины и решения

Как создать сценарий резервного копирования в Vim: упрощенное руководство

Создание резервных копий ваших файлов является важным аспектом работы программиста. И если вы используете Vim, вам может понадобиться собственный сценарий для автоматизации процесса. В этой статье мы рассмотрим, как написать сценарий резервного копирования на VIM, который будет соответствовать определенным требованиям и поможет избежать потери важной информации.

Задачи сценария

Я столкнулся с проблемой потери значительной части своего кода, и это подтолкнуло меня к созданию сценария резервного копирования. Основные требования к сценариям заключались в следующем:

  1. Увеличение номера резервной копии при каждом сохранении.
  2. Сохранение не более пяти резервных копий одновременно.

Принцип работы резервного копирования

Суть процесса заключается в том, чтобы создавать файлы резервных копий с увеличивающимся номером, например:

  • A.BOB
  • A.BOB;1
  • A.BOB;2

Таким образом, вы будете иметь возможность следить за различными версиями вашего файла.

Создание сценария для Vim

Для начала давайте рассмотрим сам сценарий. Его можно поместить в каталог плагинов как decvers.vim, и он будет выполняться каждый раз, когда вы редактируете файл.

" -*- vim -*-
" @(#) $Id: decvers.vim,v 0.1 Mark Manning
"
"   Notes: Please note that I am using five zeros as the size of the
"       backup file names. So we have 00000 and then 00001, 00002, etc...
"
    let path_name=expand("%:p")
    let file_name=expand("%:t")
    let ext_name=expand("%:e")

    let s:version_length = 5
    let s:num_zeros = strpart("000000000000000000000000",0,s:version_length)
    let s:version_subs = "^.*\\(\\d\\{" . s:version_length . "}\\)$"

    let cmd ='dir /b/on "' . path_name . ';0?*"'
    let x=system(cmd)
    let x=split(x,"\n")
    let ary_len=len(x)

    let l=0
    let high_num=0
    if( ary_len > 0 )
        while( l < ary_len )
            let a=split( x[l], "\\;" )
            let a_len = len(a) - 1
            let a_last = str2nr( a[a_len] )
            if( a_last >= high_num )
                let high_num = a_last
            endif
            let l += 1
        endwhile
    endif

    let high_num += 1
    let ext = substitute(s:num_zeros.high_num,s:version_subs,";\","")
    let new_path = expand("%:p") . ext

    let cmd = 'copy "' . path_name . '" "' . new_path . '"'
    let output = system( cmd )

    let max_backups = 5
    let cmd ='dir /b/on "' . path_name . ';0?*"'
    let x=system(cmd)
    let x=split(x,"\n")
    let ary_len=len(x)

    if( ary_len > max_backups )
        let l=0
        let ary_len = ary_len - max_backups
        if( ary_len > 0 )
            while( l < ary_len )
                let a=split( x[l], "\\;" )
                let a_len = len(a) - 1
                let a_last = str2nr( a[a_len] )
                let file_name = expand("%:p") . ";" . a_last
                let cmd = 'del "' . file_name . '"'
                let output = system( cmd )
                let l += 1
            endwhile
        endif
    endif

    finish

Проблемы с дублированием файлов

Несмотря на то, что первоначальная версия сценария работала, она создавала сразу два файла резервной копии. Причина заключалась в том, что команды, используемые для получения списка имен файлов, не останавливались после создания первой резервной копии. Это приводило к тому, что скрипт выполнялся дважды. Была необходима замена команды system на systemlist, чтобы корректно обрабатывать массивы файлов.

Устранение ошибок и дальнейшие улучшения

После тестирования сценария и анализа его работы, я обнаружил несколько моментов, которые требовали доработки:

  1. Использование systemlist: Этот метод позволяет получить список файлов без дублирования.
  2. Корректное создание имен файлов: Использование printf для создания чисел с фиксированной длиной, чтобы предотвратить путаницу с порядком номеров.
  3. Установка правильного количества резервных копий: Изменение max_backups на оптимальное число для вашего рабочего процесса.

Вот исправленный сценарий:

" Улучшенная версия сценария с использованием systemlist и printf

Заключение

Создание резервного копирования — это важная часть работы с кодом. Хотя можно прибегать к более сложным системам управления версиями, иногда полезно иметь простой и эффективный скрипт. Надеюсь, этот пример вдохновит вас на автоматизацию ваших задач и сохранение важных данных. Спасибо всем, кто поддерживал меня в этом процессе, и всем, кто вносил свой вклад в обсуждение на форумах и сообществах.

Источник

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *