OSDN Git Service

Add /c command line option
authorTakashi Sawanaka <sdottaka@users.sourceforge.net>
Mon, 9 Aug 2021 06:28:53 +0000 (15:28 +0900)
committerTakashi Sawanaka <sdottaka@users.sourceforge.net>
Mon, 9 Aug 2021 06:28:53 +0000 (15:28 +0900)
Docs/Manual/EN/Command_line.xml
Docs/Manual/JP/Command_line.xml
Src/MainFrm.cpp
Src/MainFrm.h
Src/Merge.cpp
Src/MergeCmdLineInfo.cpp
Src/MergeCmdLineInfo.h
Src/MergeDoc.cpp
Src/MergeDoc.h
Src/MergeEditView.cpp
Src/MergeEditView.h

index 1c62ec9..19b2fef 100644 (file)
@@ -78,6 +78,9 @@
       <arg choice="opt" rep="norepeat"><option>/l</option>
       <replaceable>linenumber</replaceable></arg>
 
+      <arg choice="opt" rep="norepeat"><option>/c</option>
+      <replaceable>charpos</replaceable></arg>
+
       <arg choice="opt" rep="norepeat"><option>/table-delimiter</option>
       <replaceable>delimiter</replaceable></arg>
 
     </varlistentry>
 
     <varlistentry>
+      <term><option>/c <replaceable>charpos</replaceable></option></term>
+      <listitem>
+        <para>Specifies a character position to jump to after loading the files.</para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
       <term><option>/table-delimiter <replaceable>delimiter</replaceable></option></term>
       <listitem>
         <para>Specifies a delimiter character for table editing. To specify a tab character, specify "tab", "\t", or "\x09".</para>
index 4413989..dff5c82 100644 (file)
@@ -78,6 +78,9 @@
       <arg choice="opt" rep="norepeat"><option>/l</option>
       <replaceable>linenumber</replaceable></arg>
 
+      <arg choice="opt" rep="norepeat"><option>/c</option>
+      <replaceable>charpos</replaceable></arg>
+
       <arg choice="opt" rep="norepeat"><option>/table-delimiter</option>
       <replaceable>delimiter</replaceable></arg>
 
     </varlistentry>
 
     <varlistentry>
+      <term><option>/c <replaceable>charpos</replaceable></option></term>
+      <listitem>
+        <para>ファイルを読み込んだ後にジャンプする文字位置を指定します。</para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
       <term><option>/table-delimiter <replaceable>delimiter</replaceable></option></term>
       <listitem>
         <para>テーブル編集用の区切り文字を指定します。タブ文字を指定する場合、「tab」または「\t」、「\x09」を指定してください。</para>
index 0d05486..a113f88 100644 (file)
@@ -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<const OpenImageFileParams *>(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<const OpenBinaryFileParams *>(pOpenParams));
        }
-       return ShowTextOrTableMergeDoc({}, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, pOpenParams);
+       return ShowTextOrTableMergeDoc({}, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, dynamic_cast<const OpenTextFileParams *>(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<const OpenTextFileParams*>(pOpenParams));
        case ID_MERGE_COMPARE_TABLE:
                return ShowTableMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
-                       strDesc, sReportFile, infoUnpacker, pOpenParams);
+                       strDesc, sReportFile, infoUnpacker, dynamic_cast<const OpenTextFileParams*>(pOpenParams));
        case ID_MERGE_COMPARE_HEX:
                return ShowHexMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
-                       strDesc, sReportFile, infoUnpacker);
+                       strDesc, sReportFile, infoUnpacker, dynamic_cast<const OpenBinaryFileParams*>(pOpenParams));
        case ID_MERGE_COMPARE_IMAGE:
                return ShowImgMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
-                       strDesc, sReportFile, infoUnpacker);
+                       strDesc, sReportFile, infoUnpacker, dynamic_cast<const OpenImageFileParams*>(pOpenParams));
        default:
                return ShowAutoMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
                        strDesc, sReportFile, infoUnpacker, pOpenParams);
@@ -837,9 +837,12 @@ bool CMainFrame::ShowTextOrTableMergeDoc(std::optional<bool> 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<const OpenTableFileParams*>(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<bool> 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<const CMainFrame::OpenTextFileParams*>(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<const CMainFrame::OpenTableFileParams*>(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<CDirDoc*>(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<CDirDoc*>(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());
index 43285d0..a272008 100644 (file)
@@ -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<TCHAR> m_tableDelimiter;
                std::optional<TCHAR> m_tableQuote;
                std::optional<bool> 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<bool> 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();
index 7cb5108..4d6e849 100644 (file)
@@ -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<CMainFrame::OpenFileParams> 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<CMainFrame::OpenTableFileParams *>(new CMainFrame::OpenAutoFileParams()));
+               if (auto* pOpenTextFileParams = dynamic_cast<CMainFrame::OpenTextFileParams*>(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<CMainFrame::OpenTableFileParams*>(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());
                        }
                }
        }
index 644cf19..c66f12a 100644 (file)
@@ -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;
index 77ed86c..3496c67 100644 (file)
@@ -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<TCHAR> m_cTableDelimiter; /**< Delimiter character for table editing*/
        std::optional<TCHAR> m_cTableQuote; /* Quote character for table editing *< */
        std::optional<bool> m_bTableAllowNewlinesInQuotes; /**< Allow newlines in quotes */
index ac3181c..a539d63 100644 (file)
@@ -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)
index daf489e..75ff3a0 100644 (file)
@@ -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);
index c0823ed..a705cb3 100644 (file)
@@ -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<int>(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.
index 9c3b982..0909b5b 100644 (file)
@@ -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; }