Mert Özen Her Satırda Daha İleri
Geliştirici Araçları IDE'ler — #03

IDE'de Hızlı Olmak: Navigasyon ve Shortcut'lar (VS 2026, Rider, VS Code Karşılaştırmalı)

Mert Özen 8 Kas 2026 9 dk 3 görüntülenme
IDE'de Hızlı Olmak: Navigasyon ve Shortcut'lar (VS 2026, Rider, VS Code Karşılaştırmalı)

"Kim kullanıyor" sorusunun cevabı Find in Files değil Find All References: Bookstore örneğinde grep sekiz satır buldu, Roslyn'in SymbolFinder API'si yalnız dört gerçek referans döndürdü. Go to Definition, Implementation, References ve Call Hierarchy'nin arkasındaki sorgular, Visual Studio 2026, Rider ve VS Code için Windows ve macOS kısayol tablosu, multi-caret, column selection, bookmark'lar ve keymap değiştirme.

Sürüm notu: Bu yazıdaki kodlar .NET 10 ve Microsoft.CodeAnalysis.CSharp.Workspaces 5.9.0 ile derlenip denenmiştir. Kısayollar Visual Studio 2026 (18.11), JetBrains Rider 2026.2 ve Visual Studio Code (VS Code) 1.145'in resmi kısayol dokümanlarından aktarıldı; Visual Studio 2026 Windows'a özel olduğu ve Rider bu makinede (macOS) kurulu olmadığı için bu iki IDE (Integrated Development Environment) çalıştırılmadı.

Önce Tahmin Et

Bookstore'da Order.Total property'sinin hesaplanma biçimini değiştireceksin ve önce onu kimin kullandığını bilmek istiyorsun. Repo'da grep -rn -w "Total" çalıştırıyorsun:

Invoice.cs:5:    public decimal Total { get; } = total;
Checkout.cs:16:        Console.WriteLine($"Order {order.Id} charged. Total: {order.Total}");
Checkout.cs:17:        return new Invoice(order.Total);
Checkout.cs:20:    public static string ToJson(Invoice invoice) => $$"""{ "Total": {{invoice.Total}} }""";
Payments.cs:12:    public Task<bool> ChargeAsync(Order order, CancellationToken ct) => Task.FromResult(order.Total > 0);
Payments.cs:17:    public Task<bool> ChargeAsync(Order order, CancellationToken ct) => Task.FromResult(order.Total <= 500);
Order.cs:8:    // Total is computed, never stored
Order.cs:9:    public decimal Total => Items.Sum(i => i.Quantity * i.UnitPrice);

Sekiz satır. Bunlardan kaçı gerçekten Order.Total'a referans? Tahminini yaz, sonra yazının ilk bölümünde IDE'lerin Find All References'ta kullandığı Roslyn API'si (Application Programming Interface) ile aynı soruyu soracağız.

Semantik Arama ile Metin Araması: Find All References Neden Farklı

IDE'nin navigasyon komutlarını değerli kılan şey, metni değil derleyicinin gördüğü symbol'leri aramaları. Visual Studio ve VS Code'daki C# desteği bu işi Roslyn'in SymbolFinder API'si üzerinden yapıyor; Rider kendi ReSharper motorunu kullanıyor ama soru aynı. Bookstore örneğinin dört dosyasını bir AdhocWorkspace'e yükleyip üç navigasyon komutunun arkasındaki sorguyu kendimiz çalıştırdık:

Compilation compilation = (await project.GetCompilationAsync())!;
Solution solution = project.Solution;

// Find All References: Order.Total
INamedTypeSymbol order = compilation.GetTypeByMetadataName("Bookstore.Ordering.Order")!;
ISymbol total = order.GetMembers("Total").Single();
IEnumerable<ReferencedSymbol> references = await SymbolFinder.FindReferencesAsync(total, solution);

// Go to Implementation: IPaymentGateway
INamedTypeSymbol gateway = compilation.GetTypeByMetadataName("Bookstore.Payments.IPaymentGateway")!;
IEnumerable<INamedTypeSymbol> implementations = await SymbolFinder.FindImplementationsAsync(gateway, solution);

// Call Hierarchy (gelen çağrılar): IPaymentGateway.ChargeAsync
IMethodSymbol charge = (IMethodSymbol)gateway.GetMembers("ChargeAsync").Single();
IEnumerable<SymbolCallerInfo> callers = await SymbolFinder.FindCallersAsync(charge, solution);
Compilation errors: 0
Find All References: Bookstore.Ordering.Order.Total
  Checkout.cs:16
  Checkout.cs:17
  Payments.cs:12
  Payments.cs:17
Go to Implementation: IPaymentGateway -> CardGateway, GiftCardGateway
Call Hierarchy: ChargeAsync <- Bookstore.Checkout.CheckoutService.PlaceAsync(Bookstore.Ordering.Order, System.Threading.CancellationToken)

Cevap dört. grep'in bulduğu sekiz satırın üçü başka şeyler: Invoice.Total aynı adı taşıyan başka bir property, JSON (JavaScript Object Notation) string'indeki "Total" bir metin, Order.cs:8 bir yorum. Order.cs:9 ise tanımın kendisi; Find All References onu ayrıca "definition" olarak gösterir. Tersi de doğru: grep satır başına bir kez sayar, aynı satırdaki iki Total'ı ayırt etmez; Roslyn Checkout.cs:16'da yalnız order.Total'ı sayar, string içindeki "Total:" kelimesini değil.

Bu fark, yazının en önemli kısayol kuralını veriyor: "kim kullanıyor" sorusu için Find in Files değil Find All References. Find in Files'ın yeri, symbol olmayan şeyler: log mesajları, config key'leri, route string'leri, SQL (Structured Query Language) içindeki kolon adları. İkisini karıştırmak, rename'in neden bazı yerleri kaçırdığını anlatan bir sonraki yazının da konusu.

Kodda Gezinmek: Definition, Implementation, References, Hierarchy

Navigasyon komutlarının adları üç IDE'de farklı, işlevleri aynı. Aşağıdaki tablo Microsoft Learn'deki Visual Studio kısayol listesi, JetBrains'in Rider keymap sayfası ve VS Code'un varsayılan keybinding sayfasından derlendi. Rider sütunlarında Windows için Rider'ın varsayılan keymap'i, macOS için JetBrains'in önerdiği macOS keymap'lerinden IntelliJ (macOS) kullanıldı; Visual Studio 2026 yalnız Windows'ta olduğu için tek sütun.

KomutVisual Studio 2026Rider (Windows)Rider (macOS)VS Code (Windows)VS Code (macOS)
Go to DefinitionF12Ctrl+B⌘BF12F12
Go to ImplementationCtrl+F12Ctrl+Alt+B⌥⌘BCtrl+F12⌘F12
Find All References / Find UsagesShift+F12Alt+F7⌥F7Shift+Alt+F12⇧⌥F12
Peek Definition / ReferencesAlt+F12Ctrl+Alt+F7 (Show Usages)⌥Space (Quick Definition)Alt+F12 / Shift+F12⌥F12 / ⇧F12
Her şeyde araCtrl+T, Ctrl+,, Ctrl+PÇift ShiftÇift ⇧Ctrl+P, Ctrl+T (symbol)⌘P, ⌘T (symbol)
Komut araCtrl+QCtrl+Shift+A⇧⌘ACtrl+Shift+P⇧⌘P
Dosyaya gitCtrl+Shift+TCtrl+Shift+N⇧⌘OCtrl+P⌘P
Son dosyalarCtrl+T, RCtrl+E⌘ECtrl+Tab⌃Tab
Geri / İleriCtrl+- / Ctrl+Shift+-Ctrl+Alt+Left / Ctrl+Alt+Right⌘[ / ⌘]Alt+Left / Alt+Right⌃- / ⌃⇧-
Find in FilesCtrl+Shift+FCtrl+Shift+F⇧⌘FCtrl+Shift+F⇧⌘F
Sonraki eşleşmeye imleç ekleShift+Alt+.Alt+J⌃GCtrl+D⌘D
Satırı taşıAlt+Up / Alt+DownAlt+Shift+Up / Alt+Shift+Down⌥⇧↑ / ⌥⇧↓Alt+Up / Alt+Down⌥↑ / ⌥↓
Satırı çoğaltCtrl+DCtrl+D⌘DShift+Alt+Down⇧⌥↓
Bookmark aç/kapatCtrl+K, Ctrl+KF11F3Yerleşik yokYerleşik yok

Call Hierarchy tabloda yok, çünkü üç IDE'de farklı yerde duruyor. Visual Studio'da View Call Hierarchy Ctrl+K, Ctrl+T; VS Code'da Show Call Hierarchy Windows'ta Shift+Alt+H, macOS'ta ⇧⌥H; Rider'da ise Inspect This (Ctrl+Alt+Shift+A) menüsünden Incoming Calls ve Outgoing Calls seçilir. Hepsi yukarıdaki FindCallersAsync sorgusunun bir ağaç olarak gösterilmiş hali.

Go to Implementation'ı Go to Definition'dan ayırmak, DI (Dependency Injection) kullanan bir kod tabanında günde onlarca tıklama kazandırır. CheckoutService'teki gateway.ChargeAsync çağrısında F12 seni interface'e götürür, orada iş yok; Ctrl+F12 doğrudan CardGateway ve GiftCardGateway'i listeler. Rider'da aynı sonuç Go to Implementation ile gelir, ayrıca Go to Super Method (Ctrl+U) ters yöne, base member'a gider.

Her Şeyde Ara ve Komut Ara

Üç IDE'nin en çok kullanılan iki kutusu var: biri kodda (dosya, type, member, symbol), öbürü IDE'nin kendi komutlarında arar. Visual Studio'da bunlar Code Search ve Feature Search, Rider'da Search Everywhere ve Find Action, VS Code'da Quick Open ve Command Palette. Kısayolunu bilmediğin bir şeyi menüde aramak yerine komut kutusunu aç ve adını yaz; sonuç satırında kısayol da yazar. Bir hafta boyunca bunu yaparsan en çok kullandığın on komutun kısayolu kendiliğinden ezberlenir.

Kutuların küçük dilleri de var. Visual Studio Code Search'te t:, m:, f: önekleri ve Order:43 ile satıra gitme (önceki yazıda gördük). VS Code'da Quick Open'a @ yazınca açık dosyanın symbol'leri, # ile workspace symbol'leri, : ile satır, > ile komutlar gelir. Rider'ın Search Everywhere penceresi All, Types, Files, Symbols, Actions sekmelerine ayrılır ve Tab ile sekme değiştirilir; camel case kısaltmaları anlar, CheSe yazınca CheckoutService bulunur.

Editing: Multi-Caret, Column Selection ve Satır İşlemleri

Navigasyondan sonra en çok vakit kazandıran şey, aynı değişikliği birden fazla yerde aynı anda yapmak. Tablodaki "sonraki eşleşmeye imleç ekle" kısayolu, seçili kelimenin bir sonraki geçişine ikinci bir imleç koyar; Visual Studio'da Shift+Alt+; bütün eşleşmelere birden imleç ekler, VS Code'da bunun karşılığı Ctrl+Shift+L (macOS'ta ⇧⌘L), Rider'da Select All Occurrences Ctrl+Alt+Shift+J.

Column selection (kutu seçimi) hizalı kodda işe yarar: Visual Studio ve VS Code'da Windows'ta Shift+Alt basılıyken fareyle sürüklersin (VS Code macOS'ta ⇧⌥), Visual Studio'da klavyeyle Shift+Alt+Down sütunu aşağı genişletir. Rider'da Alt basılıyken sürüklemek dikdörtgen seçim yapar, Alt+Shift+Insert column selection modunu açıp kapatır.

Bir uyarı: multi-caret, metin üzerinde çalışır. On yerde aynı adı değiştirmek istiyorsan bu bir rename'dir ve rename'in semantik olanı (F2, Ctrl+R, Ctrl+R, Shift+F6) aynı adı taşıyan alakasız symbol'lere dokunmaz. Yukarıdaki örnekte multi-caret ile Total'ları seçip değiştirsen Invoice.Total'ı ve JSON alanını da bozarsın.

Bookmark'lar uzun bir okuma oturumunda iz bırakmaya yarar. Visual Studio'da Ctrl+K, Ctrl+K ile koyup Ctrl+K, Ctrl+N ile sonrakine geçersin; Rider'da F11 isimsiz, Ctrl+F11 harf ya da rakamlı bookmark koyar, Ctrl+[rakam] ile doğrudan atlarsın. VS Code'da yerleşik bookmark yok; ya Go Back/Go Forward geçmişine güvenirsin ya da bir extension kurarsın.

Keymap Değiştirmek: Kas Hafızanı Taşımak

Bir IDE'den diğerine geçerken en büyük maliyet kas hafızası. Üç IDE de bunu azaltmanın bir yolunu sunuyor. Rider'da Settings (Ctrl+Alt+S) > Keymap'ten keymap seçilir; JetBrains'in kendi önerisi şu: ReSharper'sız düz Visual Studio deneyimin varsa Visual Studio 2022 keymap'i, IntelliJ ailesinden geliyorsan IntelliJ, VS Code'dan geliyorsan VS Code keymap'i; macOS'ta adında macOS geçen sürümü seç. VS Code'da File > Preferences > Migrate Keyboard Shortcuts from... menüsü popüler keymap extension'larını listeler; Visual Studio kısayolları için Microsoft'un Visual Studio Keymap extension'ı (ms-vscode.vs-keybindings) var. Visual Studio'da kendi kısayollarını Tools > Options > Environment > Keyboard'da değiştirir, Tools > Import and Export Settings ile yalnız kısayolları bir .vssettings dosyasına dışa aktarıp ekip arkadaşına verebilirsin.

Benim önerim: birden fazla IDE kullanıyorsan hepsinde tek bir keymap'te standartlaş. Windows'ta Visual Studio ağırlıklı çalışan biri Rider'da Visual Studio 2022 keymap'iyle, VS Code'da Visual Studio Keymap'iyle aynı F12, Shift+F12, Ctrl+F12 üçlüsünü korur. Takas da var: Rider'ın kendi dokümanı ve yardım sayfaları varsayılan keymap'i esas alır; farklı keymap seçtiğinde sayfanın üstündeki keymap seçicisini değiştirmeyi unutma.

Üretimde Dikkat

Büyük solution'da semantik arama ücretsiz değildir. Find All References bütün solution'ı derleyici gözüyle tarar; yüz projelik bir kod tabanında ilk çağrı saniyeler sürebilir ve proje yüklenmemişse (solution filter, unloaded project) o projedeki referanslar sonuçta yoktur. "Kimse kullanmıyor" demeden önce bütün projelerin yüklü olduğundan emin ol.

Reflection, DI kayıtları ve string ile çağrılan kod (nameof kullanılmayan yerler, Razor ve Angular template'leri, JSON property adları) Find All References'ta çıkmayabilir. Silmeden ya da imza değiştirmeden önce Find in Files ile metin araması yapıp iki sonucu karşılaştır.

Uzak bağlantıda (Remote Desktop, Dev Container, SSH (Secure Shell)) bazı kısayollar işletim sistemi ya da terminal tarafından yutulur; örneğin macOS'ta ⌃← gibi tuşlar Mission Control'e gidebilir. Kısayol çalışmıyorsa önce işletim sistemindeki kısayol çakışmasına bak.

Sık Düşülen Tuzaklar

Her şeyi fareyle yapmak. Solution Explorer'da klasör açıp dosya aramak, Go to File'ın bir saniyelik işine dakikalar harcar. Bir hafta boyunca menüye her uzandığında komut kutusunu kullanmayı dene.

Find in Files ile Find All References'ı karıştırmak. Birincisi metin, ikincisi symbol arar. Örnekte grep sekiz satır döndürdü, gerçek referans dörttü; ters yönde, string ile çağrılan bir kod metin aramasında görünür ama Find All References'ta görünmez.

Multi-caret ile rename yapmak. Aynı metni taşıyan farklı symbol'leri birlikte değiştirir; semantik rename kullan.

Keymap karışıklığı. Rider'da IntelliJ keymap'i, VS Code'da varsayılan, Visual Studio'da varsayılan kullanan biri aynı gün içinde üç farklı "Go to Definition" tuşuna basar. Bir keymap seç ve hepsine uygula.

macOS'ta Windows kısayollarını aramak. Rider'da macOS'ta Windows keymap'i seçersen Ctrl tuşlu kısayollar sistem kısayollarıyla çakışabilir; JetBrains bu yüzden adında macOS geçen keymap'leri öneriyor.

Küçük Bir Deneme

★☆☆ Kendi IDE'nde tablodaki on dört kısayolu dene ve çalışmayanları işaretle. Çalışmayanların keymap'ten mi, işletim sisteminden mi kaynaklandığını bul.

★★☆ Kendi kod tabanında sık kullanılan bir property seç. Önce Find in Files, sonra Find All References ile ara; iki sonuç listesinin farkını kategorilere ayır: aynı adı taşıyan başka symbol, string, yorum, reflection.

★★★ Microsoft'un açık kaynak eShop referans uygulamasını (GitHub'da dotnet/eShop) klonla ve yalnız klavye kullanarak sepete ürün ekleme isteğinin yolunu bul: HTTP (HyperText Transfer Protocol) endpoint'inden başla, handler'a, domain nesnesine ve veritabanına yazan koda kadar in. Hangi kısayolları kaç kez kullandığını not et; fareye kaç kez uzandın?

Kodda hızlı gezinmeyi öğrendik. Bir sonraki yazıda bulduğumuz kodu güvenle değiştirmeye geçiyoruz: Quick Actions ve Alt+Enter ile refactoring, .editorconfig ile code style ve rename'in yakalayamadığı yerler.