[vim/vim] Add ":curwin" command modifier that makes splits use current window (#3251)

255 views
Skip to first unread message

Yee Cheng Chin

unread,
Jul 26, 2018, 4:43:34 AM7/26/18
to vim/vim, Subscribed

Add a new command modifier that changes how splits work, similar to :vertical and :tab. The difference is that it will make the command use an existing window rather than splitting off a new window.

The user can use [count] to specify which window to use (defaults to current window) and [!] to forcefully discard a window with modified buffer.

Most of the handling happens in win_split() where it detects the command mod and pretends to split off a window. Commands like :terminal handles the modifier manually because it already has to deal with the ++curwin option.

Examples of commands affected by this:

  • help
  • split / new
  • sbuffer
  • snext
  • ptag
  • cw / copen
  • cc / cnext
  • terminal

Rationale

Just for some rationale and background for why I implemented this.

  1. I find that a lot of times I do something similar to :help | only or :tab help just to get a help page taking up a full screen. It seems to me there should just be a command that says "use the current window I have and show the help page there", instead of always having to split a window. Of course you can have two commands: :shelp and :help but that's redundant, and a better solution is to have a modifier that works across the board similar to how :vertical works.

  2. Similarly I have a custom command called :EditConfig that opens my vimrc in a split window. Again, sometimes I want to just open the vimrc without the split and I don't want to have to write two commands, or have to do :only afterwards.

  3. I have some Vim scripts that augment mksession and save out quickfix content (by calling getqflist() and getloclist() on all windows) into the extra x.vim. However, I found it really hard for Vim scripts to properly restore the quickfix windows because the session restore will have created the window splits for me, but there's no way for me to just say "window 5 is the location list display for window 3" without some complicated command scripting. Now, I can just add this line to do that: 3wincmd w | 5curwin lopen.

  • Thought: I do think it would be nice for Vim to have a "quickfix" option in sessionoptions that will do that natively.

Existing bug in Vim

Note that there's currently a bug / issue where the <mods> passed into custom commands don't retain [count] and [!] for modifiers, so you cannot do something like :2curwin! MyCommand as <mods> will just show "curwin". This is probably something that should be fixed. It also affects :tab. I think the bug is in uc_check_code().

Tests

I have not implemented any tests yet, but I could. I couldn't find any tests for existing command modifiers like :vert and :tab so I didn't have a good place to add them, but I would imagine for new functionality like this that touches a fair bit of code I should probably add some basic unit tests.

Other names

I considered naming this usewin instead of curwin. Still not sure which one is better.

Ideas for other similar commands

Following down this path, just some ideas for similar modifiers:

  • :[count]usetab: Go to a particular tab specified by [count] and make the split there. Unlike :tab this doesn't make a new tab. Can combine with :vertical and :curwin, but not :tab.

  • :[count]abovewin: Make a split above window specified by [count], kind of like how :tab makes a new tab next to a specified one. This is more flexible than :topleft (same as :0abovewin) and :botright (same as :$abovewin)


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/3251

Commit Summary

  • Add ":curwin" modifier to Vim

File Changes

Patch Links:


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub

Yee Cheng Chin

unread,
Jul 26, 2018, 5:27:36 AM7/26/18
to vim/vim, Push

@ychin pushed 1 commit.


You are receiving this because you are subscribed to this thread.

View it on GitHub

Yee Cheng Chin

unread,
Jul 26, 2018, 5:41:30 AM7/26/18
to vim/vim, Subscribed

Seems like I broke unit tests. Somehow missed that. Let me fix that first

Yee Cheng Chin

unread,
Jul 26, 2018, 6:05:02 AM7/26/18
to vim/vim, Push

@ychin pushed 1 commit.

  • 12fec21 Fix unit tests. Previously broke parsing for :confirm


You are receiving this because you are subscribed to this thread.

View it on GitHub

Yee Cheng Chin

unread,
Jul 26, 2018, 6:58:27 AM7/26/18
to vim/vim, Push

@ychin pushed 1 commit.

  • 59671a2 Fix documentation, add syntax highlight, add unit tests


You are receiving this because you are subscribed to this thread.

View it on GitHub

Yee Cheng Chin

unread,
Jul 26, 2018, 7:07:49 AM7/26/18
to vim/vim, Push

@ychin pushed 1 commit.

  • 2694d67 Minor additions to unit tests


You are receiving this because you are subscribed to this thread.

View it on GitHub

Codecov

unread,
Jul 26, 2018, 7:18:50 AM7/26/18
to vim/vim, Subscribed

Codecov Report

Merging #3251 into master will increase coverage by 0.02%.
The diff coverage is 89.39%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3251      +/-   ##
==========================================
+ Coverage   76.48%    76.5%   +0.02%     
==========================================
  Files          93       93              
  Lines      136826   136879      +53     
==========================================
+ Hits       104648   104719      +71     
+ Misses      32178    32160      -18
Impacted Files Coverage Δ
src/buffer.c 78.81% <100%> (ø) ⬆️
src/quickfix.c 93.07% <85.71%> (-0.03%) ⬇️
src/ex_cmds.c 79.81% <85.71%> (-0.23%) ⬇️
src/window.c 82.39% <87.5%> (+0.51%) ⬆️
src/ex_docmd.c 77.74% <90.47%> (+0.05%) ⬆️
src/terminal.c 74.03% <92.85%> (+0.06%) ⬆️
src/os_unix.c 57.42% <0%> (-0.14%) ⬇️
src/gui.c 49.53% <0%> (-0.06%) ⬇️
src/getchar.c 75.16% <0%> (-0.05%) ⬇️
... and 7 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0a08c63...2694d67. Read the comment docs.

Yee Cheng Chin

unread,
Jul 26, 2018, 7:40:37 AM7/26/18
to vim/vim, Push

@ychin pushed 1 commit.


You are receiving this because you are subscribed to this thread.

View it on GitHub

Yee Cheng Chin

unread,
Jul 26, 2018, 7:40:54 AM7/26/18
to vim/vim, Subscribed

Ok I believe I have fixed up everything from unit tests to documentations. Should be good to go now.

K.Takata

unread,
Jul 26, 2018, 10:20:48 AM7/26/18
to vim/vim, Subscribed

@k-takata commented on this pull request.


In runtime/doc/map.txt:

> @@ -1441,11 +1441,11 @@ The valid escape sequences are
 		expands to nothing.
 						*<mods>*
 	<mods>  The command modifiers, if specified. Otherwise, expands to
-		nothing. Supported modifiers are |:aboveleft|, |:belowright|,
-		|:botright|, |:browse|, |:confirm|, |:hide|, |:keepalt|,
-		|:keepjumps|, |:keepmarks|, |:keeppatterns|, |:leftabove|,
-		|:lockmarks|, |:noswapfile| |:rightbelow|, |:silent|, |:tab|,
-		|:topleft|, |:verbose|, and |:vertical|.
+                nothing. Supported modifiers are |:aboveleft|, |:belowright|,

Tab should be used in the help.

Yee Cheng Chin

unread,
Jul 26, 2018, 11:02:46 AM7/26/18
to vim/vim, Push

@ychin pushed 1 commit.

  • beef35f Fix docs to use tabs, not spaces


You are receiving this because you are subscribed to this thread.

View it on GitHub

Yee Cheng Chin

unread,
Jul 26, 2018, 11:04:37 AM7/26/18
to vim/vim, Subscribed

@ychin commented on this pull request.


In runtime/doc/map.txt:

> @@ -1441,11 +1441,11 @@ The valid escape sequences are
 		expands to nothing.
 						*<mods>*
 	<mods>  The command modifiers, if specified. Otherwise, expands to
-		nothing. Supported modifiers are |:aboveleft|, |:belowright|,
-		|:botright|, |:browse|, |:confirm|, |:hide|, |:keepalt|,
-		|:keepjumps|, |:keepmarks|, |:keeppatterns|, |:leftabove|,
-		|:lockmarks|, |:noswapfile| |:rightbelow|, |:silent|, |:tab|,
-		|:topleft|, |:verbose|, and |:vertical|.
+                nothing. Supported modifiers are |:aboveleft|, |:belowright|,

Ok. Just pushed a new commit with tabs.

Just wondering though. Should help docs have noet in the modeline at the end of file? It already sets ts=8.

Bram Moolenaar

unread,
Jul 28, 2018, 10:15:16 AM7/28/18
to vim/vim, Subscribed

Yee Cheng Chin wrote:

> Add a new command modifier that changes how splits work, similar to
> `:vertical` and `:tab`. The difference is that it will make the
> command use an *existing* window rather than splitting off a new

> window.
>
> The user can use `[count]` to specify which window to use (defaults to
> current window) and [!] to forcefully discard a window with modified
> buffer.
>
> Most of the handling happens in `win_split()` where it detects the
> command mod and pretends to split off a window. Commands like
> `:terminal` handles the modifier manually because it already has to
> deal with the `++curwin` option.
>
> Examples of commands affected by this:
>
> * help
> * split / new
> * sbuffer
> * snext
> * ptag
> * cw / copen
> * cc / cnext
> * terminal
>
> # Rationale

>
> Just for some rationale and background for why I implemented this.
>
> 1. I find that a lot of times I do something similar to `:help | only`

> or `:tab help` just to get a help page taking up a full screen. It
> seems to me there should just be a command that says "use the current
> window I have and show the help page there", instead of always having
> to split a window. Of course you can have two commands: `:shelp` and
> `:help` but that's redundant, and a better solution is to have a
> modifier that works across the board similar to how `:vertical` works.
>
> 2. Similarly I have a custom command called `:EditConfig` that opens
> my vimrc in a split window. Again, sometimes I want to *just* open the

> vimrc without the split and I don't want to have to write two
> commands, or have to do `:only` afterwards.
>
> 3. I have some Vim scripts that augment `mksession` and save out

> quickfix content (by calling `getqflist()` and `getloclist()` on all
> windows) into the extra `x.vim`. However, I found it really hard for

> Vim scripts to properly restore the quickfix windows because the
> session restore will have created the window splits for me, but
> there's no way for me to just say "window 5 is the location list
> display for window 3" without some complicated command scripting. Now,
> I can just add this line to do that: `3wincmd w | 5curwin lopen`.
>
> * Thought: I do think it would be nice for Vim to have a "quickfix"

> option in `sessionoptions` that will do that natively.

Hmm, for most of the commands there are non-splitting variants. It's
like for those there is a "split" modifier, but it's part of the command
name. Thus the "curwin" modifier is only useful for commands that split
by default. And :help would be the most prominent one. :terminal is
another one, for which we have the ++curwin argument.

So why not use :help ++curwin ?


--
** Hello and Welcome to the Psychiatric Hotline **
If you are obsessive-compulsive, please press 1 repeatedly.
If you are co-dependent, please ask someone to press 2.
If you have multiple personalities, please press 3, 4, 5 and 6.
If you are paranoid-delusional, we know who you are and what you want
- just stay on the line so we can trace the call.
If you are schizophrenic, listen carefully and a little voice will
tell you which number to press next.
If you are manic-depressive, it doesn't matter which number you press
- no one will answer.
If you suffer from panic attacks, push every button you can find.
If you are sane, please hold on - we have the rest of humanity on the
other line and they desparately want to ask you a few questions.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Yee Cheng Chin

unread,
Jul 28, 2018, 6:07:48 PM7/28/18
to vim/vim, Subscribed

It's like for those there is a "split" modifier, but it's part of the command name.

I think with how most command modifiers work (e.g. vertical and tab), currently split is the de facto "open a new window" command that lets other modifiers handle how to deal with it. Otherwise there is no general command that works this way, e.g. :e some_file is not modifiable in anyway.

Here are some extra points I can think of why having a dedicated :curwin modifier is desirable:

  1. [count] adds unique capability that cannot be done with a simple ++curwin option, since it lets you choose the placement of the window. This is especially important for commands that makes a new window that are context sensitive to the current window, and it's hard to make those commands show the window in the right place. E.g. let's say I'm in the following:

    +---+---+---+
    |[1]| 2 | 3 |
    +---+---+---+
    |     4     |
    +-----------+
    

    I'm editing foo.c in window 1, and I want to:

    • open the header foo.h in window 2,
    • also open current file (foo.c) in 3, and
    • open the location list in 4.

    Right now I have to do a lot of complex wincmd dances to make it work. But now I can just do the following: (Note that lopen, %, and sp are all context sensitive to current window so you can't just move to window 2/3/4 first and do the commands)

    :+curwin sp %:s/.c/.h/
    :wincmd p
    :3curwin sp
    :wincmd p
    :$curwin lopen
    

    As I mentioned in the "Rationale" part in original comment, this is also very useful in scripts as it lets you precisely place your windows especially when combined with mksession.

  2. [!] also adds a global way of incidating you want to discard a file. ++curwin option currently doesn't work that way. You can already do :terminal! ++curwin but this is actually undocumented, and :help! already means something else. Being able to say :curwin! fixes this problem and is consistent with how Vim commands generally work.

  3. It works with <mods>. Plugin authors don't need to think about exposing duplicate functionality for every command they make. It "just works" if they already support other modifiers. Only caveat is as I mentioned in original post that [count] and ! are not supported in <mods> right now, which is a problem already for :[count]tab.

  4. It will be standardized and not needing individual options added to each command. This is similar to vert and tab where you don't have to remember how to invoke individual options with a different syntax.

This does create some redundancy in commands (:curwin sp foo.txt vs :e foo.txt, :curwin term vs :term ++curwin), but I think it's ok. It allows you to approach a command in different ways, and we already have :vsp vs :vert sp or :tab new vs :tabnew.

So why not use :help ++curwin ?

In addition to terminal and help, I think the following commands would also be helped by this (this re-iterates the above points):

  • split (no arguments)
  • lopen / copen
  • User commands with <mods>
  • expand() and cmdline-special (since they are context sensitive to current window and you can use [count]curwin to apply the current command to another window)

Yee Cheng Chin

unread,
Aug 12, 2018, 12:21:26 AM8/12/18
to vim/vim, Push

@ychin pushed 1 commit.

  • 92be08b Move docs for :curwin to a slightly better place


You are receiving this because you are subscribed to this thread.

View it on GitHub

Yee Cheng Chin

unread,
Aug 22, 2018, 6:37:27 AM8/22/18
to vim/vim, Subscribed

Just rebased the code.

Also some thoughts on the how the local window state would be preserved. Right now when you split a new window (e.g. :split) the new window inherits the old one's location list, local dir, etc. [count]curwin doesn't do that currently. So when you do +curwin sp it will populate the next window with the current window's content, but it won't make the next window have the exact same local properties.

I think the current behavior is ok, but we could also make [count]curwin resets the target window's local properties to the current one too if we really want to.

Bram Moolenaar

unread,
Sep 22, 2019, 4:27:14 PM9/22/19
to vim/vim, Subscribed

Closed #3251.

Bram Moolenaar

unread,
Sep 22, 2019, 4:27:14 PM9/22/19
to vim/vim, Subscribed

I see no positive responses or thumbs-up on this PR and I don't think it has a clear usefulness. Therefore closing.

Yee Cheng Chin

unread,
Sep 22, 2019, 8:19:40 PM9/22/19
to vim/vim, Subscribed

I have actually been using this custom command almost daily combined with mksession and found it incredibly useful in being able to restore various states like quickfix and location lists in the correct windows, along the ability to do :curwin help to display help page in the current window. Oh well. I hope some other users will find this PR and comment on it.

Justin M. Keyes

unread,
Sep 22, 2019, 8:33:20 PM9/22/19
to vim/vim, Subscribed

I would think this makes more sense than adding ++curwin to every command.

Seems like Vim cannot decide if commands should be prefixed or suffixed.

Reply all
Reply to author
Forward
0 new messages