D-2, D-5: C++ 전처리 지시문 · 3-Way 덩어리 반영
D-2. C++ 문법 강조는 이미 되고 있었다. LanguageProfile.CFamily 가 확장자 아홉 가지를 맡고 예약어/주석/문자열도 들어 있다. 빠진 것은 전처리 지시문 하나였다. #include 가 # 과 include 로 쪼개져 보통 낱말처럼 칠해졌다. 줄 첫머리가 # 이면 그 줄 전체를 지시문 색으로 칠한다. C# 쪽과 같은 규칙이다. 언어표에 hasPreprocessor 를 두어 C 계열에서만 켠다. D-5. 2-Way 는 이미 됐다. 3-Way 가 잘못 동작하고 있었다. 덩어리를 BASE 에서 가져오고 있었는데 3-Way 에서 BASE 는 공통 조상이다. 저쪽(REMOTE)을 가져오는 것이 Take Theirs 이고 덩어리 반영은 그것을 줄 묶음으로 하는 것인데, BASE 를 가져오면 조상으로 되돌리는 셈이라 뜻이 전혀 달라진다. 덩어리를 묶는 기준도 모드에 맞췄다. 확인: 충돌 6개짜리 C++ 파일에서 다음 충돌 -> 이 덩어리 반영 한 번에 네 줄이 REMOTE 값으로 바뀌고 Conflict 6 -> 2. LangTest 12건 추가. 전체 424건 통과. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
4f33cacd4f
commit
5c8c942ba5
33
doc/진행상황.md
33
doc/진행상황.md
@ -127,10 +127,10 @@ CommunityToolkit 커맨드는 CommandManager 를 구독하지 않는데 이 둘
|
||||
| 상태 | 항목 |
|
||||
|---|---|
|
||||
| 대기 | D-1 주석만 다른 파일을 다른 색으로 |
|
||||
| 대기 | D-2 C++ 문법 강조 |
|
||||
| **완료** | D-2 C++ 문법 강조 (이미 되고 있었음 · 전처리 지시문만 추가) |
|
||||
| 대기 | D-3 폴더 안 전체 검색 |
|
||||
| ~~취소~~ | ~~D-4 비교 창 여러 개~~ (2026-09-09 사용자 판단으로 뺌) |
|
||||
| 대기 | D-5 덩어리 단위 반영 (2-Way 는 이미 됨 · 3-Way 확인 필요) |
|
||||
| **완료** | D-5 덩어리 단위 반영 (3-Way 에서 BASE 를 가져오던 것을 REMOTE 로) |
|
||||
| 대기 | D-6 비교 결과 텍스트 내보내기 |
|
||||
| 대기 | D-7 드래그 앤 드롭으로 열기 |
|
||||
|
||||
@ -147,6 +147,35 @@ CommunityToolkit 커맨드는 CommandManager 를 구독하지 않는데 이 둘
|
||||
|
||||
---
|
||||
|
||||
### D-2 · D-5 — **완료** (2026-09-09)
|
||||
|
||||
#### D-2. C++ 문법 강조
|
||||
|
||||
**이미 되고 있었다.** `LanguageProfile.CFamily` 가 `.c .h .cpp .hpp .cc .hh .cxx .hxx .inl` 을
|
||||
모두 맡고 있고 예약어·주석·문자열도 들어 있다. 지시서에서 확인만 하라고 적어 둔 대로 확인했다.
|
||||
|
||||
**빠진 것은 전처리 지시문 하나였다.** `#include` 는 `#` 과 `include` 로 쪼개져 보통 낱말처럼
|
||||
칠해졌다. 줄 첫머리가 `#` 이면 그 줄 전체를 지시문 색으로 칠하게 했다 - C# 쪽과 같은 규칙이다.
|
||||
같은 모양인데 언어마다 다르게 보이면 오히려 헷갈린다.
|
||||
언어표에 `hasPreprocessor` 를 두어 <b>C 계열에서만</b> 켠다. 자바·자바스크립트는 `#` 이 지시문이 아니다.
|
||||
|
||||
**검사**: `LangTest` 12건 추가(40 → 52건).
|
||||
|
||||
#### D-5. 덩어리 단위 반영
|
||||
|
||||
**2-Way 는 이미 됐다**(`이 덩어리 반영` · `Alt+Shift+→`). 확인했다.
|
||||
|
||||
**3-Way 가 잘못 동작하고 있었다.** 덩어리를 BASE 에서 가져오고 있었는데, 3-Way 에서 BASE 는
|
||||
<b>공통 조상</b>이다. 저쪽(REMOTE)을 가져오는 것이 `Take Theirs` 이고 덩어리 반영은 그것을
|
||||
줄 묶음으로 하는 것인데, BASE 를 가져오면 <b>조상으로 되돌리는 셈</b>이라 뜻이 전혀 달라진다.
|
||||
덩어리를 묶는 기준도 같이 바꿨다 - 2-Way 는 "BASE 를 가져올 수 있는 줄", 3-Way 는
|
||||
"저쪽을 가져올 수 있는 줄"이 이어진 구간이다.
|
||||
|
||||
**확인**: 충돌 6개짜리 C++ 파일에서 `다음 충돌` → `이 덩어리 반영` 한 번에
|
||||
네 줄이 REMOTE 값으로 바뀌고 `Conflict 6 → 2`, `머지 반영함 4`.
|
||||
단축키(`Alt+Shift+→`)도 같은 명령을 부르므로 함께 고쳐졌다.
|
||||
---
|
||||
|
||||
### C. 잔손질 — **완료** (2026-09-09)
|
||||
|
||||
#### C-1. 코드 위 툴팁 제거
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MergeHub.Views.Controls;
|
||||
|
||||
@ -46,6 +46,23 @@ namespace MergeHub.Services
|
||||
stillInBlockComment = false;
|
||||
}
|
||||
|
||||
// ---- 전처리 지시문 ----
|
||||
//
|
||||
// 줄 첫머리가 <c>#</c> 이면 그 줄 전체가 지시문이다(#include · #define · #ifdef).
|
||||
// C# 쪽과 같은 규칙으로 칠한다 - 같은 모양인데 언어마다 다르게 보이면 더 헷갈린다.
|
||||
// 블록 주석이 이미 열려 있던 줄은 해당 없다(i 가 0 이 아니다).
|
||||
if (profile.HasPreprocessor && i == 0)
|
||||
{
|
||||
var firstVisible = 0;
|
||||
while (firstVisible < line.Length && char.IsWhiteSpace(line[firstVisible])) firstVisible++;
|
||||
|
||||
if (firstVisible < line.Length && line[firstVisible] == '#')
|
||||
{
|
||||
tokens.Add(new CodeToken(firstVisible, line.Length - firstVisible, CodeTokenKind.Preprocessor));
|
||||
return tokens;
|
||||
}
|
||||
}
|
||||
|
||||
while (i < line.Length)
|
||||
{
|
||||
var start = i;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
@ -29,7 +29,8 @@ namespace MergeHub.Services
|
||||
bool caseSensitive = true,
|
||||
bool isCode = true,
|
||||
bool hasBraces = false,
|
||||
bool useCSharpTokenizer = false)
|
||||
bool useCSharpTokenizer = false,
|
||||
bool hasPreprocessor = false)
|
||||
{
|
||||
Name = name;
|
||||
Extensions = extensions;
|
||||
@ -41,6 +42,7 @@ namespace MergeHub.Services
|
||||
IsCode = isCode;
|
||||
HasBraces = hasBraces;
|
||||
UseCSharpTokenizer = useCSharpTokenizer;
|
||||
HasPreprocessor = hasPreprocessor;
|
||||
|
||||
var comparer = caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
|
||||
Keywords = new HashSet<string>(keywords ?? Array.Empty<string>(), comparer);
|
||||
@ -56,6 +58,12 @@ namespace MergeHub.Services
|
||||
public char[] Quotes { get; }
|
||||
public bool CaseSensitive { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <c>#include</c> · <c>#define</c> 처럼 <b>줄 첫머리의 # 지시문</b>을 쓰는 언어인지.
|
||||
/// C 계열이 그렇다. 켜 두면 그 줄 전체를 지시문 색으로 칠한다 - C# 과 같은 규칙이다.
|
||||
/// </summary>
|
||||
public bool HasPreprocessor { get; }
|
||||
|
||||
/// <summary>문법 색을 입힐 대상인지. 평문·표 형식 문서는 false 다.</summary>
|
||||
public bool IsCode { get; }
|
||||
|
||||
@ -111,7 +119,8 @@ namespace MergeHub.Services
|
||||
"inline", "operator", "new", "delete", "this", "nullptr", "true", "false",
|
||||
"using", "typedef", "sizeof", "friend", "explicit", "mutable", "constexpr"
|
||||
},
|
||||
controlKeywords: CFamilyControl, typeKeywords: CFamilyTypes, hasBraces: true);
|
||||
controlKeywords: CFamilyControl, typeKeywords: CFamilyTypes, hasBraces: true,
|
||||
hasPreprocessor: true);
|
||||
|
||||
public static readonly LanguageProfile Java = new LanguageProfile(
|
||||
"Java", new[] { ".java" },
|
||||
|
||||
@ -2193,24 +2193,40 @@ namespace MergeHub.ViewModels
|
||||
var block = BlockAround(CaretRow);
|
||||
if (block.Count == 0) return;
|
||||
|
||||
foreach (var line in block) Apply(line, requery: false);
|
||||
// 2-Way 는 BASE 를, 3-Way 는 저쪽(REMOTE)을 가져온다. BlockAround 주석 참고.
|
||||
foreach (var line in block)
|
||||
{
|
||||
if (IsThreeWay) ApplyRemote(line, requery: false);
|
||||
else Apply(line, requery: false);
|
||||
}
|
||||
|
||||
AfterEdit();
|
||||
MessageUtil.ShowSuccessToast($"{block.Count}줄 반영");
|
||||
}
|
||||
|
||||
/// <summary>그 줄이 속한 차이 덩어리. 차이가 아니면 빈 목록이다.</summary>
|
||||
/// <summary>
|
||||
/// 그 줄이 속한 차이 덩어리. 차이가 아니면 빈 목록이다.
|
||||
///
|
||||
/// <b>무엇을 가져오는지가 모드마다 다르다.</b>
|
||||
/// 2-Way : BASE 를 결과로 가져온다. 덩어리는 "BASE 를 가져올 수 있는 줄"이 이어진 구간.
|
||||
/// 3-Way : BASE 는 공통 조상이라 가져올 것이 아니다. 저쪽(REMOTE)을 가져오는 것이
|
||||
/// <c>Take Theirs</c> 이고, 덩어리 반영은 그것을 줄 묶음으로 하는 것이다.
|
||||
/// 여기서 BASE 를 가져오면 <b>조상으로 되돌리는 셈</b>이라 뜻이 전혀 달라진다.
|
||||
/// </summary>
|
||||
private List<MergeLine> BlockAround(int row)
|
||||
{
|
||||
var found = new List<MergeLine>();
|
||||
if (row < 0 || row >= Lines.Count) return found;
|
||||
if (!Lines[row].CanTakeBase) return found;
|
||||
|
||||
bool Takeable(MergeLine line) => IsThreeWay ? line.CanTakeRemote : line.CanTakeBase;
|
||||
|
||||
if (!Takeable(Lines[row])) return found;
|
||||
|
||||
var first = row;
|
||||
while (first > 0 && Lines[first - 1].CanTakeBase) first--;
|
||||
while (first > 0 && Takeable(Lines[first - 1])) first--;
|
||||
|
||||
var last = row;
|
||||
while (last + 1 < Lines.Count && Lines[last + 1].CanTakeBase) last++;
|
||||
while (last + 1 < Lines.Count && Takeable(Lines[last + 1])) last++;
|
||||
|
||||
for (var i = first; i <= last; i++) found.Add(Lines[i]);
|
||||
return found;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user