OSDN Git Service

Implement osdn.net #41528: command line option that specifies line number to jump...
authorTakashi Sawanaka <sdottaka@users.sourceforge.net>
Sat, 17 Jul 2021 00:46:45 +0000 (09:46 +0900)
committerTakashi Sawanaka <sdottaka@users.sourceforge.net>
Sat, 17 Jul 2021 00:46:45 +0000 (09:46 +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

index 15d8d5b..ddaaf1c 100644 (file)
@@ -70,6 +70,9 @@
 
       <arg choice="opt" rep="norepeat"><option>/fr</option></arg>
 
+      <arg choice="opt" rep="norepeat"><option>/l</option>
+      <replaceable>linenumber</replaceable></arg>
+
       <arg choice="opt" rep="norepeat"><option>/dl</option>
       <replaceable>leftdesc</replaceable></arg>
 
     </varlistentry>
 
     <varlistentry>
+      <term><option>/l <replaceable>linenumber</replaceable></option></term>
+      <listitem>
+        <para>Specifies a line number to jump to after loading the files.</para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
       <term><option>/dl</option></term>
       <listitem>
         <para>Specifies a description in the left side title
index 81a8efe..1747b43 100644 (file)
@@ -70,6 +70,9 @@
 
       <arg choice="opt" rep="norepeat"><option>/fr</option></arg>
 
+      <arg choice="opt" rep="norepeat"><option>/l</option>
+      <replaceable>linenumber</replaceable></arg>
+
       <arg choice="opt" rep="norepeat"><option>/dl</option>
       <replaceable>leftdesc</replaceable></arg>
 
     </varlistentry>
 
     <varlistentry>
+      <term><option>/l <replaceable>linenumber</replaceable></option></term>
+      <listitem>
+        <para>ファイルを読み込んだ後にジャンプする行番号を指定します。</para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
       <term><option>/dl</option></term>
       <listitem>
         <para>左側タイトルバーの説明を指定します。
index 7ef320b..2a949b3 100644 (file)
@@ -697,7 +697,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 PackingInfo * infoUnpacker /*= nullptr*/, int line /*= -1*/)
 {
        ASSERT(pDirDoc != nullptr);
 
@@ -726,22 +726,22 @@ bool CMainFrame::ShowAutoMergeDoc(CDirDoc * pDirDoc,
                else if (filterBin.includeFile(filepath) && CHexMergeView::IsLoadable())
                        return ShowHexMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
        }
-       return ShowTextOrTableMergeDoc({}, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
+       return ShowTextOrTableMergeDoc({}, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, line);
 }
 
 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 PackingInfo* infoUnpacker /*= nullptr*/, int line /*= -1*/)
 {
        switch (nID)
        {
        case ID_MERGE_COMPARE_TEXT:
                return GetMainFrame()->ShowTextMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
-                       strDesc, sReportFile, infoUnpacker);
+                       strDesc, sReportFile, infoUnpacker, line);
        case ID_MERGE_COMPARE_TABLE:
                return GetMainFrame()->ShowTableMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
-                       strDesc, sReportFile, infoUnpacker);
+                       strDesc, sReportFile, infoUnpacker, line);
        case ID_MERGE_COMPARE_HEX:
                return GetMainFrame()->ShowHexMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
                        strDesc, sReportFile, infoUnpacker);
@@ -750,7 +750,7 @@ bool CMainFrame::ShowMergeDoc(UINT nID, CDirDoc* pDirDoc,
                        strDesc, sReportFile, infoUnpacker);
        default:
                return GetMainFrame()->ShowAutoMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
-                       strDesc, sReportFile, infoUnpacker);
+                       strDesc, sReportFile, infoUnpacker, line);
        }
 }
 
@@ -789,7 +789,7 @@ int GetActivePaneFromFlags(int nFiles, const DWORD dwFlags[])
 bool CMainFrame::ShowTextOrTableMergeDoc(std::optional<bool> table, CDirDoc * pDirDoc,
        int nFiles, const FileLocation ifileloc[],
        const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
-       const PackingInfo * infoUnpacker /*= nullptr*/)
+       const PackingInfo * infoUnpacker /*= nullptr*/, int line /*= -1*/)
 {
        if (m_pMenus[MENU_MERGEVIEW] == nullptr)
                theApp.m_pDiffTemplate->m_hMenuShared = NewMergeViewMenu();
@@ -853,7 +853,7 @@ bool CMainFrame::ShowTextOrTableMergeDoc(std::optional<bool> table, CDirDoc * pD
                }
        }
 
-       pMergeDoc->MoveOnLoad(GetActivePaneFromFlags(nFiles, dwFlags));
+       pMergeDoc->MoveOnLoad(GetActivePaneFromFlags(nFiles, dwFlags), line, true);
 
        if (!sReportFile.empty())
                pMergeDoc->GenerateReport(sReportFile);
@@ -864,17 +864,17 @@ bool CMainFrame::ShowTextOrTableMergeDoc(std::optional<bool> table, CDirDoc * pD
 bool CMainFrame::ShowTextMergeDoc(CDirDoc* pDirDoc,
        int nFiles, const FileLocation ifileloc[],
        const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
-       const PackingInfo* infoUnpacker /*= nullptr*/)
+       const PackingInfo* infoUnpacker /*= nullptr*/, int line /*= -1*/)
 {
-       return ShowTextOrTableMergeDoc(false, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
+       return ShowTextOrTableMergeDoc(false, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, line);
 }
 
 bool CMainFrame::ShowTableMergeDoc(CDirDoc* pDirDoc,
        int nFiles, const FileLocation ifileloc[],
        const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
-       const PackingInfo* infoUnpacker /*= nullptr*/)
+       const PackingInfo* infoUnpacker /*= nullptr*/, int line /*= -1*/)
 {
-       return ShowTextOrTableMergeDoc(true, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
+       return ShowTextOrTableMergeDoc(true, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, line);
 }
 
 bool CMainFrame::ShowHexMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
@@ -930,7 +930,7 @@ bool CMainFrame::ShowImgMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocati
 }
 
 bool CMainFrame::ShowTextMergeDoc(CDirDoc* pDirDoc, int nBuffers, const String text[],
-               const String strDesc[], const String& strFileExt)
+               const String strDesc[], const String& strFileExt, int line /*= -1*/)
 {
        FileLocation fileloc[3];
        DWORD dwFlags[3] = {};
@@ -949,7 +949,7 @@ bool CMainFrame::ShowTextMergeDoc(CDirDoc* pDirDoc, int nBuffers, const String t
                }
                fileloc[nBuffer].setPath(workFile);
        }
-       return ShowTextMergeDoc(pDirDoc2, nBuffers, fileloc, dwFlags, strDesc);
+       return ShowTextMergeDoc(pDirDoc2, nBuffers, fileloc, dwFlags, strDesc, _T(""), nullptr, line);
 }
 
 /**
@@ -1065,7 +1065,7 @@ static bool AddToRecentDocs(const PathContext& paths, const unsigned flags[], bo
  */
 bool CMainFrame::DoFileOpen(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*/)
+       const PackingInfo *infoUnpacker /*= nullptr*/, const PrediffingInfo *infoPrediffer /*= nullptr*/, int line /*= -1*/)
 {
        if (pDirDoc != nullptr && !pDirDoc->CloseMergeDocs())
                return false;
@@ -1193,7 +1193,7 @@ bool CMainFrame::DoFileOpen(const PathContext * pFiles /*= nullptr*/,
                }
 
                ShowAutoMergeDoc(pDirDoc, tFiles.GetSize(), fileloc, dwFlags, strDesc, sReportFile,
-                               infoUnpacker);
+                               infoUnpacker, line);
        }
 
        if (pFiles != nullptr && (!dwFlags || !(dwFlags[0] & FFILEOPEN_NOMRU)))
@@ -1207,14 +1207,14 @@ bool CMainFrame::DoFileOpen(const PathContext * pFiles /*= nullptr*/,
 
 bool CMainFrame::DoFileOpen(UINT nID, const PathContext* pFiles /*= nullptr*/,
        const DWORD dwFlags[] /*= nullptr*/, const String strDesc[] /*= nullptr*/,
-       const String& sReportFile /*= _T("")*/, const PackingInfo *infoUnpacker /*= nullptr*/)
+       const String& sReportFile /*= _T("")*/, const PackingInfo *infoUnpacker /*= nullptr*/, int line /*= -1*/)
 {
        CDirDoc* pDirDoc = static_cast<CDirDoc*>(theApp.m_pDirTemplate->CreateNewDocument());
        FileLocation fileloc[3];
        for (int pane = 0; pane < pFiles->GetSize(); pane++)
                fileloc[pane].setPath((*pFiles)[pane]);
        return ShowMergeDoc(nID, pDirDoc, pFiles->GetSize(), fileloc,
-               dwFlags, strDesc, sReportFile, infoUnpacker);
+               dwFlags, strDesc, sReportFile, infoUnpacker, line);
 }
 
 void CMainFrame::UpdateFont(FRAMETYPE frame)
@@ -2488,7 +2488,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 PackingInfo *infoUnpacker /*= nullptr*/, int line /*= -1*/)
 {
        String ext = paths::FindExtension(file);
        TempFilePtr wTemp(new TempFile());
@@ -2502,7 +2502,7 @@ bool CMainFrame::DoSelfCompare(UINT nID, const String& file, const String strDes
                (strDesc && !strDesc[1].empty()) ? strDesc[1] : _("") };
        DWORD dwFlags[2] = {FFILEOPEN_READONLY | FFILEOPEN_NOMRU, FFILEOPEN_NOMRU};
        PathContext tmpPathContext(copiedFile, file);
-       return DoFileOpen(nID, &tmpPathContext, dwFlags, strDesc2, _T(""), infoUnpacker);
+       return DoFileOpen(nID, &tmpPathContext, dwFlags, strDesc2, _T(""), infoUnpacker, line);
 }
 
 /**
index 95e098f..1527760 100644 (file)
@@ -93,22 +93,27 @@ public:
        bool DoFileOpen(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);
+               const PackingInfo * infoUnpacker = nullptr, const PrediffingInfo * infoPrediffer = nullptr, int line = -1);
        bool DoFileOpen(UINT nID, const PathContext* pFiles = nullptr,
                const DWORD dwFlags[] = nullptr, const String strDesc[] = nullptr,
-               const String& sReportFile = _T(""), const PackingInfo* infoUnpacker = nullptr);
+               const String& sReportFile = _T(""), const PackingInfo* infoUnpacker = nullptr, int line = -1);
        bool ShowAutoMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
-               const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""), const PackingInfo * infoUnpacker = nullptr);
+               const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""),
+               const PackingInfo * infoUnpacker = nullptr, int line = -1);
        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 DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""),
+               const PackingInfo * infoUnpacker = nullptr, int line = -1);
        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 DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""),
+               const PackingInfo * infoUnpacker = nullptr, int line = -1);
        bool ShowTextMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
-               const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""), const PackingInfo * infoUnpacker = nullptr);
+               const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""),
+               const PackingInfo * infoUnpacker = nullptr, int line = -1);
        bool ShowTextMergeDoc(CDirDoc* pDirDoc, int nBuffers, const String text[],
-               const String strDesc[], const String& strFileExt);
+               const String strDesc[], const String& strFileExt, int line = -1);
        bool ShowTableMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
-               const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""), const PackingInfo * infoUnpacker = nullptr);
+               const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""),
+               const PackingInfo * infoUnpacker = nullptr, int line = -1);
        bool ShowHexMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
                const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""), const PackingInfo * infoUnpacker = nullptr);
        bool ShowImgMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
@@ -121,7 +126,7 @@ public:
        void StartFlashing();
        bool AskCloseConfirmation();
        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);
+       bool DoSelfCompare(UINT nID, const String& file, const String strDesc[] = nullptr, const PackingInfo* infoUnpacker = nullptr, int line = -1);
        static FRAMETYPE GetFrameType(const CFrameWnd * pFrame);
        static void UpdateDocTitle();
        static void ReloadMenu();
index 6e8ebfd..3cf32ca 100644 (file)
@@ -718,14 +718,14 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF
                        DWORD dwFlags[3] = {cmdInfo.m_dwLeftFlags, cmdInfo.m_dwMiddleFlags, cmdInfo.m_dwRightFlags};
                        bCompared = pMainFrame->DoFileOpen(&cmdInfo.m_Files,
                                dwFlags, strDesc, cmdInfo.m_sReportFile, cmdInfo.m_bRecurse, nullptr,
-                               infoUnpacker.get(), infoPrediffer.get());
+                               infoUnpacker.get(), infoPrediffer.get(), cmdInfo.m_nLineIndex);
                }
                else if (cmdInfo.m_Files.GetSize() > 1)
                {
                        DWORD dwFlags[3] = {cmdInfo.m_dwLeftFlags, cmdInfo.m_dwRightFlags, FFILEOPEN_NONE};
                        bCompared = pMainFrame->DoFileOpen(&cmdInfo.m_Files,
                                dwFlags, strDesc, cmdInfo.m_sReportFile, cmdInfo.m_bRecurse, nullptr,
-                               infoUnpacker.get(), infoPrediffer.get());
+                               infoUnpacker.get(), infoPrediffer.get(), cmdInfo.m_nLineIndex);
                }
                else if (cmdInfo.m_Files.GetSize() == 1)
                {
@@ -734,7 +734,7 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF
                        {
                                strDesc[0] = cmdInfo.m_sLeftDesc;
                                strDesc[1] = cmdInfo.m_sRightDesc;
-                               bCompared = pMainFrame->DoSelfCompare(IDOK, sFilepath, strDesc);
+                               bCompared = pMainFrame->DoSelfCompare(IDOK, sFilepath, strDesc, nullptr, cmdInfo.m_nLineIndex);
                        }
                        else if (IsProjectFile(sFilepath))
                        {
@@ -753,7 +753,7 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF
                                DWORD dwFlags[3] = {cmdInfo.m_dwLeftFlags, cmdInfo.m_dwRightFlags, FFILEOPEN_NONE};
                                bCompared = pMainFrame->DoFileOpen(&cmdInfo.m_Files,
                                        dwFlags, strDesc, cmdInfo.m_sReportFile, cmdInfo.m_bRecurse, nullptr,
-                                       infoUnpacker.get(), infoPrediffer.get());
+                                       infoUnpacker.get(), infoPrediffer.get(), cmdInfo.m_nLineIndex);
                        }
                }
                else if (cmdInfo.m_Files.GetSize() == 0) // if there are no input args, we can check the display file dialog flag
index db138e5..d3fd89f 100644 (file)
@@ -126,7 +126,8 @@ MergeCmdLineInfo::MergeCmdLineInfo(const TCHAR *q):
        m_bSelfCompare(false),
        m_dwLeftFlags(FFILEOPEN_NONE),
        m_dwMiddleFlags(FFILEOPEN_NONE),
-       m_dwRightFlags(FFILEOPEN_NONE)
+       m_dwRightFlags(FFILEOPEN_NONE),
+       m_nLineIndex(-1)
 {
        String exeName;
        q = EatParam(q, exeName);
@@ -364,6 +365,22 @@ void MergeCmdLineInfo::ParseWinMergeCmdLine(const TCHAR *q)
                        // -fr to set focus to the right pane
                        m_dwRightFlags |= FFILEOPEN_SETFOCUS;
                }
+               else if (param == _T("l"))
+               {
+                       // -l to set the destination line nubmer
+                       String line;
+                       q = EatParam(q, line);
+                       m_nLineIndex = _ttoi(line.c_str());
+                       if (m_nLineIndex <= 0)
+                       {
+                               m_nLineIndex = -1;
+                               m_sErrorMessages.push_back(_T("Invalid line number specified"));
+                       }
+                       else
+                       {
+                               m_nLineIndex--;
+                       }
+               }
                else if (param == _T("al"))
                {
                        // -al to auto-merge at the left pane
index 68cf101..25ff4f6 100644 (file)
@@ -64,6 +64,7 @@ public:
        int  m_nCodepage;  /**< Codepage. */
        bool m_bNoPrefs; /**< Do not load or remember options (preferences) */   
        bool m_bSelfCompare; /**< Compares the specified file with a copy of the file */
+       int m_nLineIndex; /**< Line number to jump after loading files */
 
        unsigned m_dwLeftFlags; /**< Left side file's behavior options. */
        unsigned m_dwMiddleFlags; /**< Middle side file's behavior options. */
index 81db278..a7f0a05 100644 (file)
@@ -3109,7 +3109,7 @@ bool CMergeDoc::OpenDocs(int nFiles, const FileLocation ifileloc[],
        return true;
 }
 
-void CMergeDoc::MoveOnLoad(int nPane, int nLineIndex)
+void CMergeDoc::MoveOnLoad(int nPane, int nLineIndex, bool bRealLine)
 {
        if (nPane < 0)
        {
@@ -3130,7 +3130,7 @@ void CMergeDoc::MoveOnLoad(int nPane, int nLineIndex)
                        return;
                }
        }
-       m_pView[0][nPane]->GotoLine(nLineIndex < 0 ? 0 : nLineIndex, false, nPane);
+       m_pView[0][nPane]->GotoLine(nLineIndex < 0 ? 0 : nLineIndex, bRealLine, nPane);
 }
 
 void CMergeDoc::ChangeFile(int nBuffer, const String& path, int nLineIndex)
index 3d0374c..e213492 100644 (file)
@@ -161,7 +161,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);
+       void MoveOnLoad(int nPane = -1, int nLinIndex = -1, bool bRealLine = false);
        void ChangeFile(int nBuffer, const String& path, int nLineIndex = -1);
        void RescanIfNeeded(float timeOutInSecond);
        int Rescan(bool &bBinary, IDENTLEVEL &identical, bool bForced = false);