⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 commands.cpp

📁 VIM文本编辑器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	afx_msg void OnDisable();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP ()
};

CMainDialog::CMainDialog (CWnd * pParent /* =NULL */ )
	: CDialog (CMainDialog::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMainDialog)
	m_bDevStudioEditor = FALSE;
	m_ChangeDir = -1;
	//}}AFX_DATA_INIT
}

void CMainDialog::DoDataExchange (CDataExchange * pDX)
{
	CDialog::DoDataExchange (pDX);
	//{{AFX_DATA_MAP(CMainDialog)
	DDX_Check (pDX, IDC_DEVSTUDIO_EDITOR, m_bDevStudioEditor);
	DDX_Radio(pDX, IDC_CD_SOURCE_PATH, m_ChangeDir);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP (CMainDialog, CDialog)
	//{{AFX_MSG_MAP(CMainDialog)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP ()


/////////////////////////////////////////////////////////////////////////////
// CCommands methods

STDMETHODIMP CCommands::VisVimDialog ()
{
	AFX_MANAGE_STATE (AfxGetStaticModuleState ());

	// Use m_pApplication to access the Developer Studio Application
	// object,
	// and VERIFY_OK to see error strings in DEBUG builds of your add-in
	// (see stdafx.h)

	VERIFY_OK (m_pApplication->EnableModeless (VARIANT_FALSE));

	CMainDialog Dlg;

	Dlg.m_bDevStudioEditor = g_bDevStudioEditor;
	Dlg.m_ChangeDir = g_ChangeDir;
	if (Dlg.DoModal () == IDOK)
	{
		g_bDevStudioEditor = Dlg.m_bDevStudioEditor;
		g_ChangeDir = Dlg.m_ChangeDir;

		// Save settings to registry HKEY_CURRENT_USER\Software\Vim\VisVim
		HKEY hAppKey = GetAppKey ("Vim");
		if (hAppKey)
		{
			HKEY hSectionKey = GetSectionKey (hAppKey, "VisVim");
			if (hSectionKey)
			{
				WriteRegistryInt (hSectionKey, "DevStudioEditor",
						  g_bDevStudioEditor);
				WriteRegistryInt (hSectionKey, "ChangeDir", g_ChangeDir);
				RegCloseKey (hSectionKey);
			}
			RegCloseKey (hAppKey);
		}
	}

	VERIFY_OK (m_pApplication->EnableModeless (VARIANT_TRUE));
	return S_OK;
}

STDMETHODIMP CCommands::VisVimEnable ()
{
	AFX_MANAGE_STATE (AfxGetStaticModuleState ());
	VimSetEnableState (true);
	return S_OK;
}

STDMETHODIMP CCommands::VisVimDisable ()
{
	AFX_MANAGE_STATE (AfxGetStaticModuleState ());
	VimSetEnableState (false);
	return S_OK;
}

STDMETHODIMP CCommands::VisVimToggle ()
{
	AFX_MANAGE_STATE (AfxGetStaticModuleState ());
	VimSetEnableState (! g_bEnableVim);
	return S_OK;
}

STDMETHODIMP CCommands::VisVimLoad ()
{
	AFX_MANAGE_STATE (AfxGetStaticModuleState ());

	// Use m_pApplication to access the Developer Studio Application object,
	// and VERIFY_OK to see error strings in DEBUG builds of your add-in
	// (see stdafx.h)
	//
	VERIFY_OK (m_pApplication->EnableModeless (VARIANT_FALSE));

	CComBSTR bStr;
	// Define dispatch pointers for document and selection objects
	CComPtr < IDispatch > pDispDoc, pDispSel;

	// Get a document object dispatch pointer
	VERIFY_OK (m_pApplication->get_ActiveDocument (&pDispDoc));
	if (! pDispDoc)
		return S_OK;

	BSTR FileName;
	long LineNr = -1;

	// Get the document object
	CComQIPtr < ITextDocument, &IID_ITextDocument > pDoc (pDispDoc);

	if (! pDoc)
		return S_OK;

	// Get the document name
	if (FAILED (pDoc->get_FullName (&FileName)))
		return S_OK;

	// Get a selection object dispatch pointer
	if (SUCCEEDED (pDoc->get_Selection (&pDispSel)))
	{
		// Get the selection object
		CComQIPtr < ITextSelection, &IID_ITextSelection > pSel (pDispSel);

		if (pSel)
			// Get the selection line number
			pSel->get_CurrentLine (&LineNr);
	}

	// Open the file in Vim
	VimOpenFile (FileName, LineNr);

	return S_OK;
}


//
// Here we do the actual processing and communication with Vim
//

// Set the enable state and save to registry
//
static void VimSetEnableState (BOOL bEnableState)
{
	g_bEnableVim = bEnableState;
	HKEY hAppKey = GetAppKey ("Vim");
	if (hAppKey)
	{
		HKEY hSectionKey = GetSectionKey (hAppKey, "VisVim");
		if (hSectionKey)
			WriteRegistryInt (hSectionKey, "EnableVim", g_bEnableVim);
		RegCloseKey (hAppKey);
	}
}

// Open the file 'FileName' in Vim and goto line 'LineNr'
// 'FileName' is expected to contain an absolute DOS path including the drive
// letter.
// 'LineNr' must contain a valid line number or 0, e. g. for a new file
//
static BOOL VimOpenFile (BSTR& FileName, long LineNr)
{
	// Get a dispatch id for the SendKeys method of Vim;
	// enables connection to Vim if necessary
	DISPID DispatchId;
	DispatchId = VimGetDispatchId ("SendKeys");
	if (! DispatchId)
		// OLE error, can't obtain dispatch id
		goto OleError;

	// Change Vim working directory to where the file is if desired
	VimChangeDir (FileName, DispatchId);

	// Make Vim open the file
	OLECHAR Buf[MAX_OLE_STR];
	char VimCmd[MAX_OLE_STR];
	char* s;

	// Open file
	sprintf (VimCmd, ":e %S\n", (char*) FileName);
	// Convert all \ to / 
	for (s = VimCmd; *s; ++s)
		if (*s == '\\')
			*s = '/';
	if (! VimOle.Method (DispatchId, "s", TO_OLE_STR_BUF (VimCmd, Buf)))
		goto OleError;

	if (LineNr > 0)
	{
		// Goto line
		sprintf (VimCmd, ":%d\n", LineNr);
		if (! VimOle.Method (DispatchId, "s", TO_OLE_STR_BUF (VimCmd, Buf)))
			goto OleError;
	}

	// Make Vim come to the foreground
	if (! VimOle.Method ("SetForeground"))
		VimOle.ErrDiag ();

	// We're done
	return true;

    OleError:
	// There was an OLE error
	// Check if it's the "unknown class string" error
	VimErrDiag ();
	return false;
}

// Return the dispatch id for the Vim method 'Method'
// Create the Vim OLE object if necessary
// Returns a valid dispatch id or null on error
//
static DISPID VimGetDispatchId (char* Method)
{
	// Initialize Vim OLE connection if not already done
	if (! VimOle.IsCreated ())
	{
		if (! VimOle.CreateObject ("Vim.Application"))
			return NULL;
	}

	// Get the dispatch id for the SendKeys method.
	// By doing this, we are checking if Vim is still there...
	DISPID DispatchId = VimOle.GetDispatchId ("SendKeys");
	if (! DispatchId)
	{
		// We can't get a dispatch id.
		// This means that probably Vim has been terminated.
		// Don't issue an error message here, instead
		// destroy the OLE object and try to connect once more
		VimOle.DeleteObject ();
		if (! VimOle.CreateObject ("Vim.Application"))
			// If this create fails, it's time for an error msg
			return NULL;

		if (! (DispatchId = VimOle.GetDispatchId ("SendKeys")))
			// There is something wrong...
			return NULL;
	}

	return DispatchId;
}

// Output an error message for an OLE error
// Check on the classstring error, which probably means Vim wasn't registered.
//
static void VimErrDiag ()
{
	SCODE sc = GetScode (VimOle.GetResult ());
	if (sc == CO_E_CLASSSTRING)
	{
		char Buf[256];
		sprintf (Buf, "There is no registered OLE automation server named "
			 "\"Vim.Application\".\n"
			 "Use the OLE-enabled version of Vim with VisVim and "
			 "make sure to register Vim by running \"vim -register\".");
		MessageBox (NULL, Buf, "OLE Error", MB_OK);
	}
	else
		VimOle.ErrDiag ();
}

// Change directory to the directory the file 'FileName' is in or it's parent
// directory according to the setting of the global 'g_ChangeDir':
// 'FileName' is expected to contain an absolute DOS path including the drive
// letter.
//	CD_NONE
//	CD_SOURCE_PATH
//	CD_SOURCE_PARENT
//
static void VimChangeDir (BSTR& FileName, DISPID DispatchId)
{
	if (g_ChangeDir != CD_NONE)
	{
		// Do a :cd first

		// Get the path name of the file ("dir/")
		CString StrFileName = FileName;
		char Drive[_MAX_DRIVE];
		char Dir[_MAX_DIR];
		_splitpath (StrFileName, Drive, Dir, NULL, NULL);
		// Convert to unix path name format
		for (char* s = Dir; *s; ++s)
			if (*s == '\\')
				*s = '/';

		// Construct the cd command; append /.. if cd to parent
		// directory and not in root directory
		OLECHAR Buf[MAX_OLE_STR];
		char VimCmd[MAX_OLE_STR];
		sprintf (VimCmd, ":cd %s%s%s\n", Drive, Dir,
			 g_ChangeDir == CD_SOURCE_PARENT && Dir[1] ? ".." : "");
		VimOle.Method (DispatchId, "s", TO_OLE_STR_BUF (VimCmd, Buf));
	}
}

#ifdef _DEBUG
// Print out a debug message
//
static void DebugMsg (char* Msg, char* Arg)
{
	char Buf[400];
	sprintf (Buf, Msg, Arg);
	AfxMessageBox (Buf);
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -