objek teks untuk tingkat indentasi saat ini? [duplikat]

Dec 02 2020

Katakanlah saya memiliki blok berlekuk seperti itu

int main(int argc, char **argv){
    printf ("odd numbers between 1 and 10:\n");
    // level 1
    for (int i = 1; i <= 10 ; i ++) { 
        // level 2
        if (i % 2 == 1){
            printf (" %d",i);
            // level 3
            ....
        }
        ...
    }
}

i{ akan berfungsi di sini karena indentasi terdapat di dalam kurung kurawal tetapi tidak untuk bahasa seperti python atau daftar indentasi dalam penurunan harga, dll.

Apakah mungkin untuk mendefinisikan objek teks, katakanlah iI("dalam Indentasi") atau sesuatu yang mirip dengan efek tersebut untuk beroperasi hanya pada tingkat indentasi tempat kursor berada? Jadi misalkan kita berada di ifblok (level 3) maka diIhanya akan menghapus di level indentasi itu dan begitu pula untuk level 1 itu akan menghapus semua yang ada di blok.

Jawaban

3 MaximKim Dec 02 2020 at 20:03

Ada banyak implementasi untuk objek teks indentasi - Saya kira karena cara objek "indentasi" yang berbeda didefinisikan.

Saya punya sendiri: cek https://gist.github.com/habamax/4662821a1dad716f5c18205489203a67

Dengan potongan berikut di vimrc Anda, Anda akan dapat viiatau vaimemilih indentasi:

"" Indent text object
"" Useful for python-like indentation based programming languages
func! s:indent_textobj(inner)
    if getline('.') =~ '^\s*$' let ln_start = s:detect_nearest_line() let ln_end = ln_start else let ln_start = line('.') let ln_end = ln_start endif let indent = indent(ln_start) if indent > 0 while indent(ln_start) >= indent && ln_start > 0 let ln_start = prevnonblank(ln_start-1) endwhile while indent(ln_end) >= indent && ln_end <= line('$')
            let ln_end = s:nextnonblank(ln_end+1)
        endwhile
    else
        while indent(ln_start) == 0 && ln_start > 0 && getline(ln_start) !~ '^\s*$' let ln_start -= 1 endwhile while indent(ln_start) > 0 && ln_start > 0 let ln_start = prevnonblank(ln_start-1) endwhile while indent(ln_start) == 0 && ln_start > 0 && getline(ln_start) !~ '^\s*$'
            let ln_start -= 1
        endwhile

        while indent(ln_end) == 0 && ln_end <= line('$') && getline(ln_end) !~ '^\s*$'
            let ln_end += 1
        endwhile
        while indent(ln_end) > 0 && ln_end <= line('$') let ln_end = s:nextnonblank(ln_end+1) endwhile endif if a:inner || indent == 0 let ln_start = s:nextnonblank(ln_start+1) endif if a:inner let ln_end = prevnonblank(ln_end-1) else let ln_end = ln_end-1 endif if ln_end < ln_start let ln_end = ln_start endif exe ln_end normal! V exe ln_start endfunc func! s:nextnonblank(lnum) abort let res = nextnonblank(a:lnum) if res == 0 let res = line('$')+1
    endif
    return res
endfunc


func! s:detect_nearest_line() abort
    let lnum = line('.')
    let nline = s:nextnonblank(lnum)
    let pline = prevnonblank(lnum)
    if abs(nline - lnum) > abs(pline - lnum) || getline(nline) =~ '^\s*$'
        return pline
    else
        return nline
    endif
endfunc


onoremap <silent>ii :<C-u>call <sid>indent_textobj(v:true)<CR>
onoremap <silent>ai :<C-u>call <sid>indent_textobj(v:false)<CR>
xnoremap <silent>ii :<C-u>call <sid>indent_textobj(v:true)<CR>
xnoremap <silent>ai :<C-u>call <sid>indent_textobj(v:false)<CR>