Esempio n. 1
0
	Switch* GetNextSwitch(LPCWSTR& rpsz, CEStr& szArg)
	{
		LPCWSTR psz = rpsz;
		CEStr szNext;

		if ((0 == NextArg(&psz, szNext)) && !szNext.IsPossibleSwitch())
			rpsz = psz;
		else
			szNext.Clear();

		Switch* ps = new Switch(szArg.Detach(), szNext.Detach());
		return ps;
	};
Esempio n. 2
0
LPCWSTR CRConFiles::GetFileFromConsole(LPCWSTR asSrc, CEStr& szFull)
{
	CEStr szWinPath;
	LPCWSTR pszWinPath = MakeWinPath(asSrc, mp_RCon ? mp_RCon->GetMntPrefix() : NULL, szWinPath);
	if (!pszWinPath || !*pszWinPath)
	{
		_ASSERTE(pszWinPath && *pszWinPath);
		return NULL;
	}

	if (IsFilePath(pszWinPath, true))
	{
		if (!FileExists(pszWinPath)) // otherwise it will cover directories too
			return NULL;
		szFull.Attach(szWinPath.Detach());
	}
	else
	{
		CEStr szDir;
		LPCWSTR pszDir = mp_RCon->GetConsoleCurDir(szDir, true);
		// We may get empty dir here if we are in "~" subdir
		if (!pszDir || !*pszDir)
		{
			_ASSERTE(pszDir && *pszDir && wcschr(pszDir,L'/')==NULL);
			return NULL;
		}

		// Попытаться просканировать один-два уровеня подпапок
		bool bFound = FileExistSubDir(pszDir, pszWinPath, 1, szFull);

		if (!bFound)
		{
			// git diffs style, but with backslashes (they are converted already)
			// "a/src/ConEmu.cpp" and "b/src/ConEmu.cpp"
			if (pszWinPath[0] && (pszWinPath[1] == L'\\') && wcschr(L"abicwo", pszWinPath[0]))
			{
				LPCWSTR pszSlash = pszWinPath;
				while (!bFound && ((pszSlash = wcschr(pszSlash, L'\\')) != NULL))
				{
					while (*pszSlash == L'\\')
						pszSlash++;
					if (!*pszSlash)
						break;
					bFound = FileExistSubDir(pszDir, pszSlash, 1, szFull);
					if (!bFound)
					{
						// Try to go to parent folder (useful while browsing git-diff-s)
						bFound = CheckParentFolders(pszDir, pszSlash, szFull);
					}
				}
			}
			else
			{
				// let's try to check some paths from #include
				// for example: #include "src/common/Common.h"
				LPCWSTR pszSlash = pszWinPath;
				while (*pszSlash == L'\\') pszSlash++;
				bFound = CheckParentFolders(pszDir, pszSlash, szFull);
			}
		}

		if (!bFound)
		{
			// If there is "src" subfolder in the current folder
			const wchar_t* predefined[] = {L"trunk", L"src", L"source", L"sources", NULL};
			for (size_t i = 0; !bFound && predefined[i]; ++i)
			{
				CEStr szSrc(JoinPath(pszDir, predefined[i]));
				if (DirectoryExists(szSrc))
					bFound = FileExistSubDir(szSrc, pszWinPath, 1, szFull);
			}
		}

		if (!bFound)
		{
			return NULL;
		}
	}

	if (!szFull.IsEmpty())
	{
		// "src\conemu\realconsole.cpp" --> "src\ConEmu\RealConsole.cpp"
		MakePathProperCase(szFull);
	}

	return szFull;
}
Esempio n. 3
0
bool TermX::GetSubstitute(const MOUSE_EVENT_RECORD& m, TermMouseMode MouseMode, CEStr& lsSubst)
{
	_ASSERTE(lsSubst.IsEmpty());

	if (!MouseMode)
	{
		lsSubst.Clear();
		return false;
	}

	wchar_t szSubst[16] = L"";

	// Deprecated. Mouse events mimic xterm behavior now.
	#if 0
	// http://conemu.github.io/en/VimXterm.html#Vim-scrolling-using-mouse-Wheel
	// https://github.com/Maximus5/ConEmu/issues/1007
	if ((m.dwEventFlags & MOUSE_WHEELED)
		&& (MouseMode & tmm_VIM))
	{
		// If the high word of the dwButtonState member contains
		// a positive value, the wheel was rotated forward, away from the user.
		// Otherwise, the wheel was rotated backward, toward the user.
		short dir = (short)HIWORD(m.dwButtonState);

		// Ctrl/Alt/Shift
		DWORD mods = (m.dwControlKeyState & (LEFT_ALT_PRESSED|LEFT_CTRL_PRESSED|RIGHT_ALT_PRESSED|RIGHT_CTRL_PRESSED|SHIFT_PRESSED));

		if (mods == 0)
		{
			if (dir <= 0)
				wcscpy_c(szSubst, L"\033[62~"); // <MouseDown>
			else
				wcscpy_c(szSubst, L"\033[63~"); // <MouseUp>
		}
		else if (mods == SHIFT_PRESSED)
		{
			if (dir <= 0)
				wcscpy_c(szSubst, L"\033[64~"); // <S-MouseDown>
			else
				wcscpy_c(szSubst, L"\033[65~"); // <S-MouseUp>
		}
		else
			return false;
		lsSubst.Set(szSubst);
		return true;
	}
	#endif

	if ((m.dwEventFlags & MOUSE_WHEELED)
		&& (MouseMode & tmm_SCROLL))
	{
		KEY_EVENT_RECORD k = {TRUE, 1};
		short dir = (short)HIWORD(m.dwButtonState);
		DWORD mods = (m.dwControlKeyState & (LEFT_ALT_PRESSED|LEFT_CTRL_PRESSED|RIGHT_ALT_PRESSED|RIGHT_CTRL_PRESSED|SHIFT_PRESSED));
		UINT nCount = 1;
		if (mods == 0)
		{
			k.wVirtualKeyCode = (dir > 0) ? VK_UP : VK_DOWN;
			nCount = gpConEmu->mouse.GetWheelScrollLines();
		}
		else if (mods == SHIFT_PRESSED)
		{
			k.wVirtualKeyCode = (dir > 0) ? VK_PRIOR : VK_NEXT;
		}
		else
			return false;
		CEStr lsPart;
		if (!GetSubstitute(k, lsPart) || lsPart.IsEmpty())
			return false;
		if (nCount > 1)
		{
			INT_PTR l = lsPart.GetLen();
			wchar_t* ptr = lsSubst.GetBuffer(l*nCount);
			for (UINT i = 1; i <= nCount; ++i, ptr += l)
				wcscpy_s(ptr, l+1, lsPart);
		}
		else
		{
			lsSubst.Attach(lsPart.Detach());
		}
		return true;
	}
	if (!(MouseMode & ~(tmm_VIM|tmm_SCROLL)))
		return false;


	BYTE NewBtns = (m.dwButtonState & 0x1F);
	if ((NewBtns != MouseButtons)
		|| ((m.dwEventFlags & MOUSE_WHEELED) && HIWORD(m.dwButtonState))
		|| ((LastMousePos != m.dwMousePosition)
			&& ((MouseMode & tmm_ANY)
				|| ((MouseMode & tmm_BTN) && NewBtns)))
		)
	{
		// #XTERM_MOUSE Unfortunately, szSubst is too short to pass "missed" coordinates
		// Like we do for Far events, MouseMove with RBtn pressed in tmm_ANY|tmm_BTN
		// modes would send all intermediate coordinates between two events

		BYTE code; bool released = false;
		if (NewBtns & FROM_LEFT_1ST_BUTTON_PRESSED)
			code = 0; // MB1 pressed
		else if (NewBtns & FROM_LEFT_2ND_BUTTON_PRESSED)
			code = 1; // MB2 pressed
		else if (NewBtns & RIGHTMOST_BUTTON_PRESSED)
			code = 2; // MB3 pressed
		else if (NewBtns & FROM_LEFT_3RD_BUTTON_PRESSED)
			code = 64; // MB4 pressed
		else if (NewBtns & FROM_LEFT_4TH_BUTTON_PRESSED)
			code = 64 + 1; // MB5 pressed
		else if (m.dwEventFlags & MOUSE_WHEELED)
		{
			// #XTERM_MOUSE Post multiple events if dir contains multiple notches
			short dir = (short)HIWORD(m.dwButtonState);
			if (dir > 0)
				code = 64; // MB4
			else if (dir < 0)
				code = 64 + 1; // MB5
		}
		else
		{
			released = true;
			code = 3;
		}

		if (m.dwControlKeyState & SHIFT_PRESSED)
			code |= 4;
		if (m.dwControlKeyState & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED))
			code |= 8;
		if (m.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
			code |= 16;

		if ((m.dwEventFlags & MOUSE_MOVED)
			&& (MouseMode & (tmm_BTN|tmm_ANY)))
			code |= 32;

		// (1,1) is upper left character position
		SHORT coord[] = {std::max<SHORT>(0, m.dwMousePosition.X) + 1,
			std::max<SHORT>(0, m.dwMousePosition.Y) + 1};

		if (MouseMode & tmm_XTERM)
		{
			msprintf(szSubst, countof(szSubst), L"\033[<%u;%u;%u%c",
				code, coord[0], coord[1], released ? 'm' : 'M');
		}
		else if (MouseMode & tmm_URXVT)
		{
			msprintf(szSubst, countof(szSubst), L"\033[%u;%u;%uM", code + 0x20, coord[0], coord[1]);
		}
		else
		{
			wcscpy_c(szSubst, L"\033[M");
			size_t i = wcslen(szSubst);
			szSubst[i++] = code + 32;

			// And coords. Must be in "screen" coordinate space
			for (size_t s = 0; s < 2; ++s)
			{
				// (1,1) is upper left character position
				if (!(MouseMode & tmm_UTF8))
					szSubst[i++] = std::min<unsigned>(255, coord[s] + 32);
				else if (coord[s] < 0x80)
					szSubst[i++] = coord[s];
				else if (coord[s] < 0x800)
				{
					// xterm #262: positions from 96 to 2015 are encoded as a two-byte UTF-8 sequence
					szSubst[i++] = 0xC0 + (coord[s] >> 6);
					szSubst[i++] = 0x80 + (coord[s] & 0x3F);
				}
				else
				{
					// #XTERM_MOUSE Xterm reports out-of-range positions as a NUL byte.
					szSubst[i++] = 1; // It's impossible to post NUL byte ATM
				}
			}