From: Takashi Sawanaka Date: Mon, 9 Aug 2021 06:28:53 +0000 (+0900) Subject: Add /c command line option X-Git-Tag: v2.16.15~102 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=751e35c1a46d49b533bb646ec04dc7507a87642b;p=winmerge-jp%2Fwinmerge-jp.git Add /c command line option --- diff --git a/Docs/Manual/EN/Command_line.xml b/Docs/Manual/EN/Command_line.xml index 1c62ec927..19b2fef9a 100644 --- a/Docs/Manual/EN/Command_line.xml +++ b/Docs/Manual/EN/Command_line.xml @@ -78,6 +78,9 @@ linenumber + + charpos + delimiter @@ -434,6 +437,13 @@ + + + Specifies a character position to jump to after loading the files. + + + + Specifies a delimiter character for table editing. To specify a tab character, specify "tab", "\t", or "\x09". diff --git a/Docs/Manual/JP/Command_line.xml b/Docs/Manual/JP/Command_line.xml index 44139894f..dff5c82dc 100644 --- a/Docs/Manual/JP/Command_line.xml +++ b/Docs/Manual/JP/Command_line.xml @@ -78,6 +78,9 @@ linenumber + + charpos + delimiter @@ -433,6 +436,13 @@ + + + ファイルを読み込んだ後にジャンプする文字位置を指定します。 + + + + テーブル編集用の区切り文字を指定します。タブ文字を指定する場合、「tab」または「\t」、「\x09」を指定してください。 diff --git a/Src/MainFrm.cpp b/Src/MainFrm.cpp index 0d054867c..a113f8892 100644 --- a/Src/MainFrm.cpp +++ b/Src/MainFrm.cpp @@ -708,7 +708,7 @@ FileLocationGuessEncodings(FileLocation & fileloc, int iGuessEncoding) bool CMainFrame::ShowAutoMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation ifileloc[], const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/, - const PackingInfo * infoUnpacker /*= nullptr*/, const OpenTextFileParams* pOpenParams /*= nullptr*/) + const PackingInfo * infoUnpacker /*= nullptr*/, const OpenFileParams* pOpenParams /*= nullptr*/) { ASSERT(pDirDoc != nullptr); @@ -733,32 +733,32 @@ bool CMainFrame::ShowAutoMergeDoc(CDirDoc * pDirDoc, { String filepath = ifileloc[pane].filepath + unpackedFileExtension; if (filterImg.includeFile(filepath) && CImgMergeFrame::IsLoadable()) - return ShowImgMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker); + return ShowImgMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, dynamic_cast(pOpenParams)); else if (filterBin.includeFile(filepath) && CHexMergeView::IsLoadable()) - return ShowHexMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker); + return ShowHexMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, dynamic_cast(pOpenParams)); } - return ShowTextOrTableMergeDoc({}, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, pOpenParams); + return ShowTextOrTableMergeDoc({}, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, dynamic_cast(pOpenParams)); } bool CMainFrame::ShowMergeDoc(UINT nID, CDirDoc* pDirDoc, int nFiles, const FileLocation ifileloc[], const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/, - const PackingInfo* infoUnpacker /*= nullptr*/, const OpenTextFileParams* pOpenParams /*= nullptr*/) + const PackingInfo* infoUnpacker /*= nullptr*/, const OpenFileParams* pOpenParams /*= nullptr*/) { switch (nID) { case ID_MERGE_COMPARE_TEXT: return ShowTextMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, - strDesc, sReportFile, infoUnpacker, pOpenParams); + strDesc, sReportFile, infoUnpacker, dynamic_cast(pOpenParams)); case ID_MERGE_COMPARE_TABLE: return ShowTableMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, - strDesc, sReportFile, infoUnpacker, pOpenParams); + strDesc, sReportFile, infoUnpacker, dynamic_cast(pOpenParams)); case ID_MERGE_COMPARE_HEX: return ShowHexMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, - strDesc, sReportFile, infoUnpacker); + strDesc, sReportFile, infoUnpacker, dynamic_cast(pOpenParams)); case ID_MERGE_COMPARE_IMAGE: return ShowImgMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, - strDesc, sReportFile, infoUnpacker); + strDesc, sReportFile, infoUnpacker, dynamic_cast(pOpenParams)); default: return ShowAutoMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, pOpenParams); @@ -837,9 +837,12 @@ bool CMainFrame::ShowTextOrTableMergeDoc(std::optional table, CDirDoc * pD { CMergeDoc::TableProps props = CMergeDoc::MakeTablePropertiesByFileName( pOpenParams->m_fileExt.empty() ? fileloc[0].filepath : pOpenParams->m_fileExt, true, false); - props.delimiter = pOpenParams->m_tableDelimiter.value_or(props.delimiter); - props.quote = pOpenParams->m_tableQuote.value_or(props.quote); - props.allowNewlinesInQuotes = pOpenParams->m_tableAllowNewlinesInQuotes.value_or(props.allowNewlinesInQuotes); + if (const auto* pOpenTableFileParams = dynamic_cast(pOpenParams)) + { + props.delimiter = pOpenTableFileParams->m_tableDelimiter.value_or(props.delimiter); + props.quote = pOpenTableFileParams->m_tableQuote.value_or(props.quote); + props.allowNewlinesInQuotes = pOpenTableFileParams->m_tableAllowNewlinesInQuotes.value_or(props.allowNewlinesInQuotes); + } pMergeDoc->SetPreparedTableProperties(props); } @@ -876,7 +879,11 @@ bool CMainFrame::ShowTextOrTableMergeDoc(std::optional table, CDirDoc * pD } } - pMergeDoc->MoveOnLoad(GetActivePaneFromFlags(nFiles, dwFlags), pOpenParams ? pOpenParams->m_line : -1, true); + pMergeDoc->MoveOnLoad( + GetActivePaneFromFlags(nFiles, dwFlags), + pOpenParams ? pOpenParams->m_line : -1, + true, + pOpenParams ? pOpenParams->m_char: -1); if (!sReportFile.empty()) pMergeDoc->GenerateReport(sReportFile); @@ -902,7 +909,7 @@ bool CMainFrame::ShowTableMergeDoc(CDirDoc* pDirDoc, bool CMainFrame::ShowHexMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[], const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/, - const PackingInfo * infoUnpacker /*= nullptr*/) + const PackingInfo * infoUnpacker /*= nullptr*/, const OpenBinaryFileParams* pOpenParams /*= nullptr*/) { if (m_pMenus[MENU_HEXMERGEVIEW] == nullptr) theApp.m_pHexMergeTemplate->m_hMenuShared = NewHexMergeViewMenu(); @@ -925,7 +932,7 @@ bool CMainFrame::ShowHexMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocati bool CMainFrame::ShowImgMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[], const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/, - const PackingInfo * infoUnpacker /*= nullptr*/) + const PackingInfo * infoUnpacker /*= nullptr*/, const OpenImageFileParams* pOpenParams /*= nullptr*/) { CImgMergeFrame *pImgMergeFrame = new CImgMergeFrame(); if (!CImgMergeFrame::menu.m_hMenu) @@ -1043,7 +1050,7 @@ static bool AddToRecentDocs(const PathContext& paths, const unsigned flags[], const String desc[], bool recurse, const String& filter, const PackingInfo *infoUnpacker, const PrediffingInfo *infoPrediffer, - UINT nID, const CMainFrame::OpenTextFileParams *pOpenParams) + UINT nID, const CMainFrame::OpenFileParams *pOpenParams) { ASSERT(paths.GetSize() <= 3); const TCHAR *lmr= (paths.GetSize() == 2) ? _T("lr") : _T("lmr"); @@ -1082,30 +1089,36 @@ static bool AddToRecentDocs(const PathContext& paths, } if (pOpenParams) { - if (pOpenParams->m_line >= 0) - params += strutils::format(_T("/l %d "), pOpenParams->m_line + 1); - if (!pOpenParams->m_fileExt.empty()) - params += _T("/fileext ") + pOpenParams->m_fileExt + _T(" "); - if (pOpenParams->m_tableDelimiter.has_value()) + if (const auto* pOpenTextFileParams = dynamic_cast(pOpenParams)) { - String delim = strutils::to_charstr(*pOpenParams->m_tableDelimiter); - if (*pOpenParams->m_tableDelimiter == '\'') - delim = _T("sq"); - else if (*pOpenParams->m_tableDelimiter == '"') - delim = _T("dq"); - params += strutils::format(_T("/table-delimiter %s "), delim); + if (pOpenTextFileParams->m_line >= 0) + params += strutils::format(_T("/l %d "), pOpenTextFileParams->m_line + 1); + if (!pOpenTextFileParams->m_fileExt.empty()) + params += _T("/fileext ") + pOpenTextFileParams->m_fileExt + _T(" "); } - if (pOpenParams->m_tableQuote.has_value()) + if (const auto* pOpenTableFileParams = dynamic_cast(pOpenParams)) { - String quote = strutils::to_charstr(*pOpenParams->m_tableQuote); - if (*pOpenParams->m_tableDelimiter == '\'') - quote = _T("sq"); - else if (*pOpenParams->m_tableDelimiter == '"') - quote = _T("dq"); - params += strutils::format(_T("/table-quote %s "), quote); + if (pOpenTableFileParams->m_tableDelimiter.has_value()) + { + String delim = strutils::to_charstr(*pOpenTableFileParams->m_tableDelimiter); + if (*pOpenTableFileParams->m_tableDelimiter == '\'') + delim = _T("sq"); + else if (*pOpenTableFileParams->m_tableDelimiter == '"') + delim = _T("dq"); + params += strutils::format(_T("/table-delimiter %s "), delim); + } + if (pOpenTableFileParams->m_tableQuote.has_value()) + { + String quote = strutils::to_charstr(*pOpenTableFileParams->m_tableQuote); + if (*pOpenTableFileParams->m_tableDelimiter == '\'') + quote = _T("sq"); + else if (*pOpenTableFileParams->m_tableDelimiter == '"') + quote = _T("dq"); + params += strutils::format(_T("/table-quote %s "), quote); + } + if (pOpenTableFileParams->m_tableAllowNewlinesInQuotes.has_value()) + params += strutils::format(_T("/table-allownewlinesinquotes %d "), *pOpenTableFileParams->m_tableAllowNewlinesInQuotes); } - if (pOpenParams->m_tableAllowNewlinesInQuotes.has_value()) - params += strutils::format(_T("/table-allownewlinesinquotes %d "), *pOpenParams->m_tableAllowNewlinesInQuotes); } if (infoUnpacker && !infoUnpacker->GetPluginPipeline().empty()) { @@ -1144,7 +1157,7 @@ bool CMainFrame::DoFileOrFolderOpen(const PathContext * pFiles /*= nullptr*/, const DWORD dwFlags[] /*= nullptr*/, const String strDesc[] /*= nullptr*/, const String& sReportFile /*= T("")*/, bool bRecurse /*= false*/, CDirDoc* pDirDoc/*= nullptr*/, const PackingInfo *infoUnpacker /*= nullptr*/, const PrediffingInfo *infoPrediffer /*= nullptr*/, - UINT nID /*= 0*/, const OpenTextFileParams *pOpenParams /*= nullptr*/) + UINT nID /*= 0*/, const OpenFileParams *pOpenParams /*= nullptr*/) { if (pDirDoc != nullptr && !pDirDoc->CloseMergeDocs()) return false; @@ -1288,7 +1301,7 @@ bool CMainFrame::DoFileOpen(UINT nID, const PathContext* pFiles, const DWORD dwFlags[] /*= nullptr*/, const String strDesc[] /*= nullptr*/, const String& sReportFile /*= _T("")*/, const PackingInfo *infoUnpacker /*= nullptr*/, const PrediffingInfo *infoPrediffer /*= nullptr*/, - const OpenTextFileParams *pOpenParams /*= nullptr*/) + const OpenFileParams *pOpenParams /*= nullptr*/) { ASSERT(pFiles != nullptr); CDirDoc* pDirDoc = static_cast(theApp.m_pDirTemplate->CreateNewDocument()); @@ -1817,7 +1830,7 @@ void CMainFrame::OnSaveConfigData() */ bool CMainFrame::DoFileNew(UINT nID, int nPanes, const String strDesc[], const PrediffingInfo *infoPrediffer /*= nullptr*/, - const OpenTextFileParams *pOpenParams) + const OpenFileParams *pOpenParams) { CDirDoc *pDirDoc = static_cast(theApp.m_pDirTemplate->CreateNewDocument()); @@ -2302,7 +2315,8 @@ BOOL CMainFrame::CreateToolbar() /** @brief Load toolbar images from the resource. */ void CMainFrame::LoadToolbarImages() { - const int toolbarNewImgSize = MulDiv(16, GetSystemMetrics(SM_CXSMICON), 16) * (1 + GetOptionsMgr()->GetInt(OPT_TOOLBAR_SIZE)); + const int toolbarNewImgSize = MulDiv(16, GetSystemMetrics(SM_CXSMICON), 16) * + (1 + std::clamp(GetOptionsMgr()->GetInt(OPT_TOOLBAR_SIZE), 0, ID_TOOLBAR_HUGE - ID_TOOLBAR_SMALL)); const int toolbarOrgImgSize = toolbarNewImgSize <= 20 ? 16 : 32; CToolBarCtrl& BarCtrl = m_wndToolBar.GetToolBarCtrl(); @@ -2579,7 +2593,7 @@ bool CMainFrame::DoOpenConflict(const String& conflictFile, const String strDesc bool CMainFrame::DoSelfCompare(UINT nID, const String& file, const String strDesc[] /*= nullptr*/, const PackingInfo *infoUnpacker /*= nullptr*/, const PrediffingInfo *infoPrediffer /*= nullptr*/, - const OpenTextFileParams *pOpenParams /*= nullptr*/) + const OpenFileParams *pOpenParams /*= nullptr*/) { String ext = paths::FindExtension(file); TempFilePtr wTemp(new TempFile()); diff --git a/Src/MainFrm.h b/Src/MainFrm.h index 43285d0c9..a27200871 100644 --- a/Src/MainFrm.h +++ b/Src/MainFrm.h @@ -69,13 +69,43 @@ public: FRAME_OTHER, /**< No frame? */ }; - struct OpenTextFileParams + struct OpenFileParams { + virtual ~OpenFileParams() {} + }; + + struct OpenTextFileParams : public OpenFileParams + { + virtual ~OpenTextFileParams() {} int m_line = -1; + int m_char = -1; + String m_fileExt; + }; + + struct OpenTableFileParams : public OpenTextFileParams + { + virtual ~OpenTableFileParams() {} std::optional m_tableDelimiter; std::optional m_tableQuote; std::optional m_tableAllowNewlinesInQuotes; - String m_fileExt; + }; + + struct OpenBinaryFileParams : public OpenFileParams + { + virtual ~OpenBinaryFileParams() {} + int m_address = -1; + }; + + struct OpenImageFileParams : public OpenFileParams + { + virtual ~OpenImageFileParams() {} + int m_x = -1; + int m_y = -1; + }; + + struct OpenAutoFileParams : public OpenTableFileParams, public OpenBinaryFileParams, public OpenImageFileParams + { + virtual ~OpenAutoFileParams() {} }; CMainFrame(); @@ -102,25 +132,25 @@ public: const DWORD dwFlags[] = nullptr, const String strDesc[] = nullptr, const String& sReportFile = _T(""), bool bRecurse = false, CDirDoc *pDirDoc = nullptr, const PackingInfo * infoUnpacker = nullptr, const PrediffingInfo * infoPrediffer = nullptr, - UINT nID = 0, const OpenTextFileParams *pOpenParams = nullptr); + UINT nID = 0, const OpenFileParams *pOpenParams = nullptr); bool DoFileOpen(UINT nID, const PathContext* pFiles, const DWORD dwFlags[] = nullptr, const String strDesc[] = nullptr, const String& sReportFile = _T(""), const PackingInfo* infoUnpacker = nullptr, const PrediffingInfo * infoPrediffer = nullptr, - const OpenTextFileParams *pOpenParams = nullptr); + const OpenFileParams *pOpenParams = nullptr); bool DoFileNew(UINT nID, int nPanes, const String strDesc[] = nullptr, const PrediffingInfo * infoPrediffer = nullptr, - const OpenTextFileParams *pOpenParams = nullptr); + const OpenFileParams *pOpenParams = nullptr); bool DoOpenConflict(const String& conflictFile, const String strDesc[] = nullptr, bool checked = false); bool DoSelfCompare(UINT nID, const String& file, const String strDesc[] = nullptr, const PackingInfo* infoUnpacker = nullptr, const PrediffingInfo * infoPrediffer = nullptr, - const OpenTextFileParams* pOpenParams = nullptr); + const OpenFileParams* pOpenParams = nullptr); bool ShowAutoMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[], const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""), - const PackingInfo * infoUnpacker = nullptr, const OpenTextFileParams *pOpenParams = nullptr); + const PackingInfo * infoUnpacker = nullptr, const OpenFileParams *pOpenParams = nullptr); bool ShowMergeDoc(UINT nID, CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[], const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""), - const PackingInfo * infoUnpacker = nullptr, const OpenTextFileParams *pOpenParams = nullptr); + const PackingInfo * infoUnpacker = nullptr, const OpenFileParams *pOpenParams = nullptr); bool ShowTextOrTableMergeDoc(std::optional table, CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[], const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""), const PackingInfo * infoUnpacker = nullptr, const OpenTextFileParams *pOpenParams = nullptr); @@ -134,10 +164,10 @@ public: const PackingInfo * infoUnpacker = nullptr, const OpenTextFileParams *pOpenParams = nullptr); bool ShowHexMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[], const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""), - const PackingInfo * infoUnpacker = nullptr); + const PackingInfo * infoUnpacker = nullptr, const OpenBinaryFileParams *pOpenParams = nullptr); bool ShowImgMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[], const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""), - const PackingInfo * infoUnpacker = nullptr); + const PackingInfo * infoUnpacker = nullptr, const OpenImageFileParams *pOpenParams = nullptr); void UpdateResources(); void ClearStatusbarItemCount(); diff --git a/Src/Merge.cpp b/Src/Merge.cpp index 7cb51088f..4d6e84974 100644 --- a/Src/Merge.cpp +++ b/Src/Merge.cpp @@ -712,16 +712,25 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF strDesc[2] = cmdInfo.m_sRightDesc; } - CMainFrame::OpenTextFileParams openParams; - openParams.m_line = cmdInfo.m_nLineIndex; - openParams.m_fileExt = cmdInfo.m_sFileExt; - if (cmdInfo.m_nWindowType == MergeCmdLineInfo::TABLE) + std::unique_ptr pOpenParams; + if (cmdInfo.m_nWindowType == MergeCmdLineInfo::TEXT) + pOpenParams.reset(new CMainFrame::OpenTextFileParams()); + else if (cmdInfo.m_nWindowType == MergeCmdLineInfo::TABLE) + pOpenParams.reset(new CMainFrame::OpenTableFileParams()); + else + pOpenParams.reset(static_cast(new CMainFrame::OpenAutoFileParams())); + if (auto* pOpenTextFileParams = dynamic_cast(pOpenParams.get())) { - openParams.m_tableDelimiter = cmdInfo.m_cTableDelimiter; - openParams.m_tableQuote = cmdInfo.m_cTableQuote; - openParams.m_tableAllowNewlinesInQuotes = cmdInfo.m_bTableAllowNewlinesInQuotes; + pOpenTextFileParams->m_line = cmdInfo.m_nLineIndex; + pOpenTextFileParams->m_char = cmdInfo.m_nCharIndex; + pOpenTextFileParams->m_fileExt = cmdInfo.m_sFileExt; + } + if (auto* pOpenTableFileParams = dynamic_cast(pOpenParams.get())) + { + pOpenTableFileParams->m_tableDelimiter = cmdInfo.m_cTableDelimiter; + pOpenTableFileParams->m_tableQuote = cmdInfo.m_cTableQuote; + pOpenTableFileParams->m_tableAllowNewlinesInQuotes = cmdInfo.m_bTableAllowNewlinesInQuotes; } - if (cmdInfo.m_Files.GetSize() > 2) { cmdInfo.m_dwLeftFlags |= FFILEOPEN_CMDLINE; @@ -730,14 +739,14 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF DWORD dwFlags[3] = {cmdInfo.m_dwLeftFlags, cmdInfo.m_dwMiddleFlags, cmdInfo.m_dwRightFlags}; bCompared = pMainFrame->DoFileOrFolderOpen(&cmdInfo.m_Files, dwFlags, strDesc, cmdInfo.m_sReportFile, cmdInfo.m_bRecurse, nullptr, - infoUnpacker.get(), infoPrediffer.get(), nID, &openParams); + infoUnpacker.get(), infoPrediffer.get(), nID, pOpenParams.get()); } else if (cmdInfo.m_Files.GetSize() > 1) { DWORD dwFlags[3] = {cmdInfo.m_dwLeftFlags, cmdInfo.m_dwRightFlags, FFILEOPEN_NONE}; bCompared = pMainFrame->DoFileOrFolderOpen(&cmdInfo.m_Files, dwFlags, strDesc, cmdInfo.m_sReportFile, cmdInfo.m_bRecurse, nullptr, - infoUnpacker.get(), infoPrediffer.get(), nID, &openParams); + infoUnpacker.get(), infoPrediffer.get(), nID, pOpenParams.get()); } else if (cmdInfo.m_Files.GetSize() == 1) { @@ -747,7 +756,7 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF strDesc[0] = cmdInfo.m_sLeftDesc; strDesc[1] = cmdInfo.m_sRightDesc; bCompared = pMainFrame->DoSelfCompare(nID, sFilepath, strDesc, - infoUnpacker.get(), infoPrediffer.get(), &openParams); + infoUnpacker.get(), infoPrediffer.get(), pOpenParams.get()); } else if (IsProjectFile(sFilepath)) { @@ -766,7 +775,7 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF DWORD dwFlags[3] = {cmdInfo.m_dwLeftFlags, cmdInfo.m_dwRightFlags, FFILEOPEN_NONE}; bCompared = pMainFrame->DoFileOrFolderOpen(&cmdInfo.m_Files, dwFlags, strDesc, cmdInfo.m_sReportFile, cmdInfo.m_bRecurse, nullptr, - infoUnpacker.get(), infoPrediffer.get(), nID, &openParams); + infoUnpacker.get(), infoPrediffer.get(), nID, pOpenParams.get()); } } else if (cmdInfo.m_Files.GetSize() == 0) // if there are no input args, we can check the display file dialog flag @@ -779,7 +788,7 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF } else { - bCompared = pMainFrame->DoFileNew(nID, 2, strDesc, infoPrediffer.get(), &openParams); + bCompared = pMainFrame->DoFileNew(nID, 2, strDesc, infoPrediffer.get(), pOpenParams.get()); } } } diff --git a/Src/MergeCmdLineInfo.cpp b/Src/MergeCmdLineInfo.cpp index 644cf1953..c66f12a92 100644 --- a/Src/MergeCmdLineInfo.cpp +++ b/Src/MergeCmdLineInfo.cpp @@ -130,6 +130,7 @@ MergeCmdLineInfo::MergeCmdLineInfo(const TCHAR* q) , m_dwMiddleFlags(FFILEOPEN_NONE) , m_dwRightFlags(FFILEOPEN_NONE) , m_nLineIndex(-1) + , m_nCharIndex(-1) { String exeName; q = EatParam(q, exeName); @@ -406,6 +407,22 @@ void MergeCmdLineInfo::ParseWinMergeCmdLine(const TCHAR *q) m_nLineIndex--; } } + else if (param == _T("c")) + { + // -c to set the destination character position + String charpos; + q = EatParam(q, charpos); + m_nCharIndex = _ttoi(charpos.c_str()); + if (m_nCharIndex <= 0) + { + m_nCharIndex = -1; + m_sErrorMessages.push_back(_T("Invalid character position specified")); + } + else + { + m_nCharIndex--; + } + } else if (param == _T("table-delimiter")) { String value; diff --git a/Src/MergeCmdLineInfo.h b/Src/MergeCmdLineInfo.h index 77ed86cea..3496c67c0 100644 --- a/Src/MergeCmdLineInfo.h +++ b/Src/MergeCmdLineInfo.h @@ -76,6 +76,7 @@ public: bool m_bSelfCompare; /**< Compares the specified file with a copy of the file */ bool m_bNewCompare; /**< Show a new blank window */ int m_nLineIndex; /**< Line number to jump after loading files */ + int m_nCharIndex; /**< Character position to jump after loading files */ std::optional m_cTableDelimiter; /**< Delimiter character for table editing*/ std::optional m_cTableQuote; /* Quote character for table editing *< */ std::optional m_bTableAllowNewlinesInQuotes; /**< Allow newlines in quotes */ diff --git a/Src/MergeDoc.cpp b/Src/MergeDoc.cpp index ac3181c79..a539d63b3 100644 --- a/Src/MergeDoc.cpp +++ b/Src/MergeDoc.cpp @@ -3293,7 +3293,7 @@ bool CMergeDoc::OpenDocs(int nFiles, const FileLocation ifileloc[], return true; } -void CMergeDoc::MoveOnLoad(int nPane, int nLineIndex, bool bRealLine) +void CMergeDoc::MoveOnLoad(int nPane, int nLineIndex, bool bRealLine, int nCharIndex) { if (nPane < 0) { @@ -3314,7 +3314,7 @@ void CMergeDoc::MoveOnLoad(int nPane, int nLineIndex, bool bRealLine) return; } } - m_pView[0][nPane]->GotoLine(nLineIndex < 0 ? 0 : nLineIndex, bRealLine, nPane); + m_pView[0][nPane]->GotoLine(nLineIndex < 0 ? 0 : nLineIndex, bRealLine, nPane, true, nCharIndex); } void CMergeDoc::ChangeFile(int nBuffer, const String& path, int nLineIndex) diff --git a/Src/MergeDoc.h b/Src/MergeDoc.h index daf489ee2..75ff3a0d4 100644 --- a/Src/MergeDoc.h +++ b/Src/MergeDoc.h @@ -162,7 +162,7 @@ public: bool OpenDocs(int nFiles, const FileLocation fileloc[], const bool bRO[], const String strDesc[]); int LoadFile(CString sFileName, int nBuffer, bool & readOnly, const FileTextEncoding & encoding); - void MoveOnLoad(int nPane = -1, int nLinIndex = -1, bool bRealLine = false); + void MoveOnLoad(int nPane = -1, int nLinIndex = -1, bool bRealLine = false, int nCharIndex = -1); void ChangeFile(int nBuffer, const String& path, int nLineIndex = -1); void RescanIfNeeded(float timeOutInSecond); int Rescan(bool &bBinary, IDENTLEVEL &identical, bool bForced = false); diff --git a/Src/MergeEditView.cpp b/Src/MergeEditView.cpp index c0823ed55..a705cb319 100644 --- a/Src/MergeEditView.cpp +++ b/Src/MergeEditView.cpp @@ -3245,8 +3245,9 @@ void CMergeEditView::OnTransformWithScript() * it is apparent line (including deleted lines) * @param [in] pane Pane index of goto target pane (0 = left, 1 = right). * @param [in] bMoveAnchor if true the anchor is moved to nLine + * @param [in] nChar Destination character position */ -void CMergeEditView::GotoLine(UINT nLine, bool bRealLine, int pane, bool bMoveAnchor) +void CMergeEditView::GotoLine(UINT nLine, bool bRealLine, int pane, bool bMoveAnchor, int nChar) { CMergeDoc *pDoc = GetDocument(); CSplitterWnd *pSplitterWnd = GetParentSplitter(this, false); @@ -3267,7 +3268,7 @@ void CMergeEditView::GotoLine(UINT nLine, bool bRealLine, int pane, bool bMoveAn nApparentLine = pDoc->m_ptBuf[pane]->ComputeApparentLine(nRealLine); } CPoint ptPos; - ptPos.x = 0; + ptPos.x = nChar == -1 ? 0 : nChar; ptPos.y = nApparentLine; // Scroll line to center of view @@ -3281,21 +3282,13 @@ void CMergeEditView::GotoLine(UINT nLine, bool bRealLine, int pane, bool bMoveAn int nGroup = m_bDetailView ? 0 : m_nThisGroup; CMergeEditView* pView = GetDocument()->GetView(nGroup, nPane); pView->ScrollToSubLine(nScrollLine); - if (ptPos.y < pView->GetLineCount()) - { - pView->SetCursorPos(ptPos); - if (bMoveAnchor) - pView->SetAnchor(ptPos); - pView->SetSelection(pView->GetAnchor(), ptPos); - } - else - { - CPoint ptPos1(0, pView->GetLineCount() - 1); - pView->SetCursorPos(ptPos1); - if (bMoveAnchor) - pView->SetAnchor(ptPos1); - pView->SetSelection(pView->GetAnchor(), ptPos1); - } + CPoint pt = (ptPos.y < pView->GetLineCount()) ? ptPos : CPoint(ptPos.x, pView->GetLineCount() - 1); + pt.x = std::clamp(static_cast(pt.x), 0, pView->GetLineLength(pt.y)); + pView->SetCursorPos(pt); + if (bMoveAnchor) + pView->SetAnchor(pt); + pView->SetSelection(pView->GetAnchor(), pt); + pView->EnsureVisible(pt); } // If goto target is another view - activate another view. diff --git a/Src/MergeEditView.h b/Src/MergeEditView.h index 9c3b9826d..0909b5bca 100644 --- a/Src/MergeEditView.h +++ b/Src/MergeEditView.h @@ -126,7 +126,7 @@ public: virtual void GetLineColors2 (int nLineIndex, DWORD ignoreFlags , COLORREF & crBkgnd, COLORREF & crText, bool & bDrawWhitespace); void WMGoto() { OnWMGoto(); }; - void GotoLine(UINT nLine, bool bRealLine, int pane, bool bMoveAnchor = true); + void GotoLine(UINT nLine, bool bRealLine, int pane, bool bMoveAnchor = true, int nChar = -1); int GetTopLine() const { return m_nTopLine; } using CCrystalTextView::GetScreenLines; int GetTopSubLine() const { return m_nTopSubLine; }