您的位置:58脚本 > vimscript切换窗口 Vimscript 切换

vimscript切换窗口 Vimscript 切换

2023-04-12 11:32 Vim教程

vimscript切换窗口 Vimscript 切换

vimscript切换窗口 Vimscript 切换

vimscript切换窗口

在开头前几章我们曾讲过怎么在Vim里设置选项。 对于布尔选项,我们可以使用set someoption!来"切换"选项。 如果我们能给这个命令创建一个映射,那就再好不过了。

执行下面的命令:

:nnoremap <leader>N :setlocal number!<cr>

在normal模式中按下<leader>N看看。Vim将会在开启和关闭行号显示之间切换。 像这样的"切换"映射是十分方便的,因此我们就不需要两个独立的键来开/关。

不幸的是,这只对布尔选项起作用。如果我们想要切换一个非布尔选项,还需要做更多的工作。

切换选项

从创建一个可以切换选项的函数,以及调用该函数的映射开始吧。 把下面的代码加入到你的~/.vimrc(或一个~/.vim/plugin/中的独立文件,如果你想要的话):

nnoremap <leader>f :call FoldColumnToggle()<cr>

function! FoldColumnToggle()
    echom &foldcolumn
endfunction

保存并source文件,然后按下<leader>f试试看。Vim显示当前foldcolumn选项的值。 如果你不熟悉这个选项,阅读:help foldcolumn再继续。

让我们添加真正的切换功能。修改代码成这样:

nnoremap <leader>f :call FoldColumnToggle()<cr>

function! FoldColumnToggle()
    if &foldcolumn
        setlocal foldcolumn=0
    else
        setlocal foldcolumn=4
    endif
endfunction

保存并source文件,然后试试看。每次你按下它Vim将显示或隐藏折叠状态条(fold column)。

if语句判断&foldcolumn是否为真(记住Vim把0看作假而其他数字为真)。 如果是,把它设成0(隐藏它)。否则就设置它为4。就是这么简单。

你可以使用一个简单的函数像这样来切换任何以0代表关,以其他数字代表开的选项。

切换其他东西

我们的梦想不应止于切换选项。还有一个我们想切换的东西是quickfix窗口。 依然以之前的骨架代码作为起点。加入下面的代码到你的文件:

nnoremap <leader>q :call QuickfixToggle()<cr>

function! QuickfixToggle()
    return
endfunction

这个映射暂时什么都不干。让我们把它转变成其他稍微有点用的东西(不过还没有彻底完成)。 把代码改成这样:

nnoremap <leader>q :call QuickfixToggle()<cr>

function! QuickfixToggle()
    copen
endfunction

保存并source文件。如果现在你试一下这个映射,你就会看到一个空荡荡的quickfix窗口。

为了达到实现切换功能的目的,我们将选择一个既快捷又肮脏的手段:全局变量。 把代码改成这样:

nnoremap <leader>q :call QuickfixToggle()<cr>

function! QuickfixToggle()
    if g:quickfix_is_open
        cclose
        let g:quickfix_is_open = 0
    else
        copen
        let g:quickfix_is_open = 1
    endif
endfunction

我们干的事情十分简单 —— 每次调用函数时,我们用一个全局变量来储存quickfix窗口的开关状态。

保存并source文件,接着执行映射试试看。Vim将抱怨变量尚未定义!那么我们先把变量初始化吧。

nnoremap <leader>q :call QuickfixToggle()<cr>

let g:quickfix_is_open = 0

function! QuickfixToggle()
    if g:quickfix_is_open
        cclose
        let g:quickfix_is_open = 0
    else
        copen
        let g:quickfix_is_open = 1
    endif
endfunction

保存并source文件,接着试一下映射。成功了!

改进

我们的切换函数可以工作,但还留有一些问题。

第一个问题是,假设用户用:copen:cclose手动开关窗口,我们的全局变量将不会刷新。 实际上这不会是个大问题,因为大多数情况下用户会用这个映射开关窗口,万一没有打开,他们也会再按一次。

这又是关于写Vimscript代码的重要经验:如果你试图处理每一个边际条件,你将陷在里面,而且不会有任何进展。

在大多数情况下,先推出可工作(而且即使不能工作也不会造成破坏)的代码然后回过头改善, 要比耗费许多小时苛求完美好得多。除外你正在开发一个很可能有很多人用到的插件。 在这种情况下它才值得耗费时日来达到无懈可击的程度,让用户满意并减少bug报告。

重新加载窗口/缓冲区

我们的函数的另外一个问题是,当用户已经打开了quickfix窗口,并执行这个映射时, Vim关闭了窗口,接着把他们弹到上一个分割中,而不是送他们回之前的地方。 如果你仅仅想快速查看一下quickfix窗口然后继续工作,发生这种事是让人恼怒的。

为了解决这个问题,我们将引入一种写Vim插件时非常有用的惯用法。把你的代码改成这样:

nnoremap <leader>q :call QuickfixToggle()<cr>

let g:quickfix_is_open = 0

function! QuickfixToggle()
    if g:quickfix_is_open
        cclose
        let g:quickfix_is_open = 0
        execute g:quickfix_return_to_window . "wincmd w"
    else
        let g:quickfix_return_to_window = winnr()
        copen
        let g:quickfix_is_open = 1
    endif
endfunction

我们在映射中加入了新的两行。其中一行(在else分支)设置了另一个全局变量,来保存执行:copen时的当前窗口序号。

另一行(在if分支)执行以那个序号作前缀的wincmd w,来告诉Vim跳转到对应窗口。

我们的解决方法又一次不是无懈可击的,用户可能在两次执行映射之间打开或关闭新的分割。 即使这样,它还是适合于大多数场合,所以目前这已经够好的了。

在大多数程序中,这种手工保存全局状态的伎俩会遭到谴责,但对于一个非常短小的Vimscript函数而言, 它既快捷又肮脏,却能不辱使命,完成重任。

练习

阅读:help foldcolumn.

阅读:help winnr()

阅读:help ctrl-w_w.

阅读:help wincmd.

在需要的地方加上s:<SID>来把函数限定在独自的命名空间中。

阅读全文
以上是58脚本为你收集整理的vimscript切换窗口 Vimscript 切换全部内容。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。
相关文章
  • vimscript教程 Vimscript 发布

    vimscript教程 Vimscript 发布

    现在你拥有了足够的Vimscript技能来打造能帮助许多人的Vim插件。 这一章涉及如何把你的插件发布在网上,以便人们获取,还有如何...

  • redis 命令 Redis Mget 命令

    redis 命令 Redis Mget 命令

    Redis Mget 命令Redis 字符串(string) Redis Mget 命令返回所有(一个或多个)给定 key 的值。如果给定的 key 里面,有某个 key 不...

  •  PostgreSQL table_privileges

    PostgreSQL table_privileges

    视图table_privileges标识在表或视图上所有被授予的特权,这些特权必须是被一个当前已被启用角色授出或者被授予给一个当前已被启...

  •  PostgreSQL view_column_usage

    PostgreSQL view_column_usage

    视图view_column_usage标识被使用在一个视图的查询表达式(定义该视图的SELECT语句)中的所有列。只有当包含一列的表被一个当前...

  •  PostgreSQL Tcl 过程名

    PostgreSQL Tcl 过程名

    在PostgreSQL,同一个函数名可以被用于不同的函数定义,只要它们的参数个数或者类型不同。不过,Tcl 要求所有过程名必须能区分。...

  •  PostgreSQL 外部数据包装器查询规划

    PostgreSQL 外部数据包装器查询规划

    FDW回调函数GetForeignRelSize、GetForeignPaths、GetForeignPlan、PlanForeignModify、GetForeignJoinPaths、GetForeignUpperPa...

  •  PostgreSQL 教程

    PostgreSQL 教程

    欢迎来到PostgreSQL教程。下面的几章将为那些新接触PostgreSQL、关系数据库概念和 SQL 语言的读者给出一个简单介绍。我们只假定...

  •  PostgreSQL 模式

    PostgreSQL 模式

    5.9.1. 创建模式5.9.2. 公共模式5.9.3. 模式搜索路径5.9.4. 模式和权限5.9.5. 系统目录模式5.9.6. 使用模式5.9.7. 可移植性 一个...

  •  PostgreSQL column_column_usage

    PostgreSQL column_column_usage

    视图column_column_usage标识依赖于同一表中的另一个基本列生成的所有列。只包含当前启用的角色所拥有的表。表36.10.column_colu...

  •  PostgreSQL pg_foreign_data_wrapper

    PostgreSQL pg_foreign_data_wrapper

    目录pg_foreign_data_wrapper存储外部数据包装器定义。外部数据包装器是一种访问位于外部服务器上数据的机制。表51.23.pg_foreig...

© 2024 58脚本 58jiaoben.com 版权所有 联系我们
桂ICP备12005667号-28 Powered by CMS