为什么这个功能“跳过”在线63? [英] Why does this function "skip" on line 63?

查看:103
本文介绍了为什么这个功能“跳过”在线63?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图修改这个了不起的VIM脚本,不过原来的和我的修改版本都有一个疯狂的错误,其中有时光标显示在错误的地方。我可以做的最简单的例子是下面的71行文本文件。请注意,复制文件时,空格是非常重要的。

 <?php 

/ **
*一些愚蠢的方法
*
* @param字符串一些愚蠢的字符串
* /
函数someFunction()
{
global $ class, $ cv,$ go,$ pae;
全球$消息,$计数器,$ ltn;
全球$ sh,$ sub,$ temp;

$ charsets = array(
'us',
$ b'si',
'pr',
'op',
'co',
'pa',
'av',
'pr',
'al',

'pc' ,
'pe',
'pi',
'pp',

'su',
'qu',

'de',
'ze',
'xo',
'mo',
'wo',
'de',
'mo',
'de',
'mo',
'dr',
'mo',
'de',
' mo',

'ev',
'pa',
'so',
'ms',
'bu',
'at',
'cu',
'pr',

'de',
'mo',
'nv',
'nl',
'nf',
'ne',
'nq',
'nt'
);




$ b

这是与.vimrc相关的文件,其中的函数为:

  set cul 
hi CursorLine term = none cterm = none ctermbg = 20
set nu
set statusline + =%{WhatFunctionAreWeIn()}
set laststatus = 2

fun WhatFunctionAreWeIn()
let strList = [while,foreach,ifelse, if,else,try,catch,case]
let foundcontrol = 1
let position =

正常mz

while(foundcontrol)

让foundcontrol = 0


这里的想法是回到
之前的非空白字符,最后一次悬挂开放{并检查它是否是密切的paran。

如果是这样,那么转到匹配的开放paren并在它之前搜索


如果不是,那么继续检查关键字。


正常[{
?\

let tempchar = getline(。)[col(。) - 1]
if(match(tempchar,))> = 0)
normal%$ b $对于strList
中的项目,b(b,b,s,b,b,endif,b,b,b,b, )> = 0)
let position = item。 - 。position
let foundcontrol = 1
break
endif
endfor

if(foundcontrol == 0)
normal`z
return tempstring.position
endif
endwhile
normal`z
return tempstring.position
endfun

从文件开头开始,按 j ,直到您到达第63行。请注意高亮ed cursorline停留在正确的行(63)上,但光标显示在第55行。直接跳转到第63行不会触发错误,只需重复按 j 直到您去那条线会。



为什么会发生这种情况,我该如何解决这个问题?请注意,当光标出现在错误的位置时,按下z实际上会将光标捕捉到正确的位置。这是在Kubuntu 11.10的VIM 7.3.154上。



编辑:
我注意到在其他安装中测试(Debian,CentOS )该错误不是确定的,它偶尔会发生,但不在每个系统上的相同位置!您可以通过按 j 来测试此代码,并注意您可能绑定的任何PHP文件中的光标位置。我会说每百行中有一行触发了光标出现在错误位置的错误。

解决方案

p>我被这个函数的逻辑弄得有些困惑,但我怀疑它是导致问题的?\ S 。它向后搜索非空白字符,并在文件底部到达顶端时将其包装到文件底部。



尝试替换两个出现的<$ c
$ b $ $ p $ call search('\S','bW ')

(这里 b 标志搜索)

编辑(第二次尝试) >



该函数还会导致视图周围出现大量跳跃。这样做的根源是不断设置标记 mz 并跳来跳去。在vimscripts中更好的方法是使用以下命令来保存当前视图(而不是 normal mz ):

<$这保存了光标位置
让view = winsaveview()这样可以保存窗口视图
pre $ let pos = getpos(。)您可以使用这些恢复视图:

 <$> 

c $ c> call cursor(pos)将光标位置恢复为pos
call winrestview(view)将窗口视图恢复为view
调用游标(pos)
来代替返回命令之前调用winrestview(view)> z
这确保了该函数不会修改窗口的外观,并使得使用更愉快。



希望这有助于您!


I am trying to modify this terrific VIM script however both the original and my modified version have a maddening bug in which sometimes the cursor is shown in the wrong place. The simplest example that I could make is the 71 line text file below. Note that whitespace is important when copying the file.

<?php

/**
* Some silly method
*
* @param    string    Some silly string
*/
function someFunction()
{
    global $class, $cv, $go, $pae;
    global $messages, $counters, $ltn;
    global $sh, $sub, $temp;

    $charsets = array(
        'us',

        'si',
        'pr',
        'op',
        'co',
        'pa',
        'av',
        'pr',
        'al',

        'pc',
        'pe',
        'pi',
        'pp',

        'su',
        'qu',

        'de',
        'ze',
        'xo',
        'mo',
        'wo',
        'de',
        'mo',
        'de',
        'mo',
        'dr',
        'mo',
        'de',
        'mo',

        'ev',
        'pa',
        'so',
        'ms',
        'bu',
        'at',
        'cu',
        'pr',

        'de',
        'mo',
        'nv',
        'nl',
        'nf',
        'ne',
        'nq',
        'nt'
    );

}

This is the relevant .vimrc file with the function:

set cul
hi CursorLine term=none cterm=none ctermbg=20
set nu
set statusline+=%{WhatFunctionAreWeIn()}
set laststatus=2

fun WhatFunctionAreWeIn()
    let strList = ["while", "foreach", "ifelse", "if else", "for", "if", "else", "try", "catch", "case"]
    let foundcontrol = 1
    let position = ""

    normal mz

    while (foundcontrol)

        let foundcontrol = 0


        " The idea here is to go back to non-whitespace character before
        " the last hanging open { and to check if it is a close paran.

        " If so, then go to the matching open paren and search for the
        " preceding it.

        " If not, then go ahead and check the keyword right there.


        normal [{
        ?\S

        let tempchar = getline(".")[col(".") - 1]
        if (match(tempchar, ")") >=0 )
            normal %
            ?\S
        endif

        let tempstring = getline(".")

        for item in strList
            if( match(tempstring,item) >= 0 )
                let position = item . " - " . position
                let foundcontrol = 1
                break
            endif
        endfor

        if(foundcontrol == 0)
            normal `z
            return tempstring.position
        endif
    endwhile
    normal `z
    return tempstring.position
endfun

Starting from the beginning of the file, press j repeatedly until you get to line 63. Note that the highlighted cursorline stays on the correct line (63) but the cursor is shown on line 55. Jumping directly to line 63 won't trigger the bug, only pressing j repeatedly until you get to that line will.

Why does that happen, and how can I fix it? Note that when the cursor appears to be in the wrong place, pressing ``z` does in fact snap the cursor to the correct location. This is on VIM 7.3.154 on Kubuntu 11.10.

EDIT: I notice by testing in other installs (Debian, CentOS) that the bug is not determinate, it happens occasionally but not in the same place on every system! You can test this code by pressing j and paying attention to the cursor location in whatever PHP files that you might have strung about. I would say that about one line out of every hundred lines triggers the bug in which the cursor appears to be in the wrong place.

解决方案

I'm slightly confused by the logic of this function, but I suspect it is the ?\S which is causing the problems. It is searching backwards for a non-whitespace character, and wrapping around to the bottom of the file once it has reached the top.

Try replacing both occurrences of ?\S with

call search('\S','bW')

(Here the b flag searches backwards, and W prevents wrapping around the file.)

EDIT (2nd attempt)

The function also causes lots of jumping around of the view. The root of this is continually setting the mark mz and jumping to and fro. A better approach in vimscripts is to use the following commands to save the current view (instead of normal mz):

let pos=getpos(".")          " This saves the cursor position
let view=winsaveview()       " This saves the window view

You can then use these to restore the view:

call cursor(pos)             " This restores the cursor position to that of "pos"
call winrestview(view)       " This restores the window view to that of "view"

So I would use call cursor(pos) instead of `z and call winrestview(view) just before the return commands. This ensures that the function doesn't modify the appearance of the window, and makes for more pleasant usage.

Hope this helps!

这篇关于为什么这个功能“跳过”在线63?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆