7

Like Vim: When it starts it takes you to another "buffer". When vim closes, the user sees the previous content of the command prompt.

Does anybody know how to do this using C#?

Thanks

Edit: The user would no longer see the output of the application. Hope that explains it better.

robertoprs
  • 157
  • 9
  • 1
    The example you describe is how a C# console application would currently work if invoked from a command line; if you execute a console app, then close it down, you are returned to your previous command line. Or am I missing something? – Dutts Feb 21 '13 at 08:33
  • I think the poster means that any output from the app should no longer be on the console, but rather what was there prior to execution. – Matt Feb 21 '13 at 08:37
  • @Richard Applications like dir or cat will spew on the same console "buffer". Applications like vim redraw a lot of text on your console window, but after closing it, the user goes back to seeing the commands he or she typed, including vim. All the output that vim put on the window is gone. Let me know if I'm not explaining myself correctly – robertoprs Feb 21 '13 at 08:39
  • Your explanation is fine, but no-one has understood it yet! I don't have a suggestion for you sorry.. – Kieren Johnstone Feb 21 '13 at 08:45
  • If you want to understand the question better [run Vim](http://www.vim.org/download.php#pc) from the command line (you don't need to install, just unzip and run vim.exe) and then type `:q` to quit - the previous contents of the console re-appears. – Justin Feb 21 '13 at 08:56
  • 1
    @robertoprs oh I see your point, yes, sorry I misinterpreted your question. I don't know of any way you can do this in native C#, you may have to dig into the Windows API through PInvoke, I'm sorry I coulnd't help. – Dutts Feb 21 '13 at 09:13

3 Answers3

5

I figured this out by looking at the Vim source code the relevant bits can be found in os_win32.c in the mch_init function, I've copied and pasted the relevant bit here

    /* Obtain handles for the standard Console I/O devices */
    if (read_cmd_fd == 0)
    g_hConIn =  GetStdHandle(STD_INPUT_HANDLE);
    else
    create_conin();
    g_hConOut = GetStdHandle(STD_OUTPUT_HANDLE);

#ifdef FEAT_RESTORE_ORIG_SCREEN
    /* Save the initial console buffer for later restoration */
    SaveConsoleBuffer(&g_cbOrig);
    g_attrCurrent = g_attrDefault = g_cbOrig.Info.wAttributes;
#else
    /* Get current text attributes */
    GetConsoleScreenBufferInfo(g_hConOut, &csbi);
    g_attrCurrent = g_attrDefault = csbi.wAttributes;
#endif
    if (cterm_normal_fg_color == 0)
    cterm_normal_fg_color = (g_attrCurrent & 0xf) + 1;
    if (cterm_normal_bg_color == 0)
    cterm_normal_bg_color = ((g_attrCurrent >> 4) & 0xf) + 1;

    /* set termcap codes to current text attributes */
    update_tcap(g_attrCurrent);

    GetConsoleCursorInfo(g_hConOut, &g_cci);
    GetConsoleMode(g_hConIn,  &g_cmodein);
    GetConsoleMode(g_hConOut, &g_cmodeout);

#ifdef FEAT_TITLE
    SaveConsoleTitleAndIcon();
    /*
     * Set both the small and big icons of the console window to Vim's icon.
     * Note that Vim presently only has one size of icon (32x32), but it
     * automatically gets scaled down to 16x16 when setting the small icon.
     */
    if (g_fCanChangeIcon)
    SetConsoleIcon(g_hWnd, g_hVimIcon, g_hVimIcon);
#endif

So it simply saves the console information (including the title and icon) and then restores it again on exit.

Unfortunately the Console class doesn't provide access to the contents of the screen buffer, so to do this you are going to need to P/Invoke into the relevant Win32 functions.

Alternatively the Win32 console actually supports multiple screen buffers which might be an easier way to implement this - rather than copy the existing screen buffer simply create a new one with the CreateConsoleScreenBuffer and set that buffer to be the one currently shown using SetConsoleActiveScreenBuffer. Again the Console class unfortunately doesn't support multiple screen buffers so you will need P/Invoke to do this. Also the Console class always writes to the screen buffer that was active at the point the application was launched, so if you swap out the active screen buffer the Console class will still be writing to the old screen buffer (which is no longer visible) - to get around this you would need to P/Invoke all of your console access, see Working with Console Screen Buffers in .NET .

Justin
  • 84,773
  • 49
  • 224
  • 367
  • Thanks! You are right, I should have looked at the code. I forget some projects are still open source even in the Windows world. I had bumped into CreateConsoleScreenBuffer thanks to jgauffin answer, but saving the state of the previous buffer is a great idea! – robertoprs Feb 21 '13 at 15:56
  • 1
    Turns out saving the original buffer content is necessary, as it is cleared when the buffer is not active. – robertoprs Feb 22 '13 at 07:40
0

You can do it by writing old content to the console buffer as described here: How can I write fast colored output to Console?

Community
  • 1
  • 1
jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • ..how are you proposing to get the old content? – Kieren Johnstone Feb 21 '13 at 12:34
  • I upvoted this because I found it useful. I did not know about PInvoke so I was not aware I could call Win32 APIs from C# code. Thanks to this I found CreateConsoleScreenBuffer. Justin's answer is more detailed, but this was good enough to unblock me. – robertoprs Feb 21 '13 at 16:03
-3

I believe Vim records its history of open files and most probably it buffers them as well, like a backup copy. The idea to do the same in C# is to implement a file buffer, some kind of storage which would record and keep track of things you want - input parameters, etc.

Another problem here is that Vim (like Vi) has command mode which one would need to implement in C# as well. Now this depends what exactly you want to accomplish with your C# program, is that's an editor, then fine, in any case, you have to distinguish between command and other modes.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
x-silencer
  • 13
  • 1
  • 1
    This has very little to do with the question. –  Feb 21 '13 at 08:44
  • I believe the OP's question was a bit hit in the dark - not easy to understand at all. I answered what I'd thought was correct. – x-silencer Feb 21 '13 at 08:50
  • 1
    The question makes sense to me. Open a command prompt. Start vim. Notice how vim appears in that same window. Exit vim. Notice how no bits of vim remain visible. Now the question is how to do get that working from C#. –  Feb 21 '13 at 08:53
  • Well if that's the case, then it has nothing to do with Vim, but with the terminal itself. – x-silencer Feb 21 '13 at 08:57