{"id":34088,"date":"2025-11-11T02:01:06","date_gmt":"2025-11-10T23:01:06","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/"},"modified":"2025-11-11T02:01:06","modified_gmt":"2025-11-10T23:01:06","slug":"go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/","title":{"rendered":"Go ile Metin D\u00fczenleyici Olu\u015fturma: \u0130mleci Hareket Ettirme Sanat\u0131"},"content":{"rendered":"<p><body><\/p>\n<p>Go programlama diliyle kendi metin d\u00fczenleyicinizi geli\u015ftirirken imle\u00e7 y\u00f6netimi nas\u0131l yap\u0131l\u0131r? Bu kapsaml\u0131 rehberde, klavye girdilerini i\u015fleyerek imleci sorunsuz bir \u015fekilde hareket ettirme tekniklerini ad\u0131m ad\u0131m \u00f6\u011freneceksiniz.<\/p>\n<p>Modern yaz\u0131l\u0131m geli\u015ftirme d\u00fcnyas\u0131nda metin d\u00fczenleyiciler, g\u00fcnl\u00fck i\u015f ak\u0131\u015f\u0131m\u0131z\u0131n temel ta\u015flar\u0131ndan biridir. VS Code, Sublime Text veya Neovim gibi ara\u00e7lar, milyarlarca sat\u0131r kodun yaz\u0131lmas\u0131na, okunmas\u0131na ve d\u00fczenlenmesine olanak tan\u0131r. Peki, bunca geli\u015fmi\u015f ara\u00e7 varken neden kendi metin d\u00fczenleyicinizi s\u0131f\u0131rdan yazmaya kalk\u0131\u015fmal\u0131s\u0131n\u0131z? Bu soruya verilecek ilk cevap, \u00f6\u011frenme s\u00fcrecinin kendisidir. Bir metin d\u00fczenleyicinin i\u00e7 i\u015fleyi\u015fini anlamak, i\u015fletim sistemleriyle etkile\u015fimden, terminal kontrol\u00fcne, veri yap\u0131lar\u0131 tasar\u0131m\u0131na ve performans optimizasyonuna kadar geni\u015f bir yelpazede derinlemesine bilgi edinmenizi sa\u011flar. Go gibi modern, performans odakl\u0131 ve e\u015fzamanl\u0131l\u0131k \u00f6zellikleriyle \u00f6ne \u00e7\u0131kan bir dil se\u00e7mek ise bu yolculu\u011fu daha da keyifli ve \u00f6\u011fretici hale getirir.<\/p>\n<p>Kendi metin d\u00fczenleyicinizi yazman\u0131n bir ba\u015fka \u00f6nemli nedeni de kontrol arzusudur. Mevcut d\u00fczenleyiciler ne kadar g\u00fc\u00e7l\u00fc olursa olsun, bazen sizin tam olarak istedi\u011finiz bir \u00f6zelli\u011fi sunmayabilir ya da belirli bir i\u015f y\u00fck\u00fc i\u00e7in gereksiz yere a\u011f\u0131r olabilir. Kendi d\u00fczenleyicinizi in\u015fa ederek, ihtiya\u00e7lar\u0131n\u0131za m\u00fckemmel \u015fekilde uyan, hafif ve \u00f6zelle\u015ftirilebilir bir ara\u00e7 yaratma g\u00fcc\u00fcne sahip olursunuz. \u00d6zellikle terminal tabanl\u0131 uygulamalar (TUI &#8211; Terminal User Interface) geli\u015ftirirken, Go&#8217;nun basitlik, h\u0131z ve \u00e7apraz platform deste\u011fi gibi avantajlar\u0131 parlar. Bir TUI uygulamas\u0131, sunucu ortamlar\u0131nda veya uzaktan ba\u011flant\u0131larda grafik aray\u00fcz gerektirmeden \u00e7al\u0131\u015fabilme esnekli\u011fi sunar ki bu da bir\u00e7ok geli\u015ftirme senaryosunda kritik bir ihtiya\u00e7t\u0131r.<\/p>\n<p>Bu s\u00fcre\u00e7te kar\u015f\u0131la\u015faca\u011f\u0131n\u0131z en temel ancak en can al\u0131c\u0131 zorluklardan biri, imle\u00e7 y\u00f6netimidir. \u0130mle\u00e7, kullan\u0131c\u0131n\u0131n nerede oldu\u011funu ve nereye yaz\u0131 yazaca\u011f\u0131n\u0131 g\u00f6steren g\u00f6rsel bir i\u015farettir. Klavyeden gelen her bir tu\u015f darbesine do\u011fru \u015fekilde tepki vermek, imleci metin i\u00e7inde sorunsuz bir \u015fekilde hareket ettirmek, sat\u0131r ba\u015flar\u0131na, sonlar\u0131na veya dosya sonuna do\u011fru kayd\u0131rmak, bir metin d\u00fczenleyicinin &#8220;canl\u0131&#8221; hissetmesini sa\u011flayan temel unsurdur. Yanl\u0131\u015f bir imle\u00e7 hareketi, kullan\u0131c\u0131 deneyimini do\u011frudan olumsuz etkileyebilir ve d\u00fczenleyiciyi kullan\u0131lamaz hale getirebilir. Bu makalede, Go kullanarak bir metin d\u00fczenleyicide imleci nas\u0131l hareket ettirece\u011fimizin perde arkas\u0131na inecek, ad\u0131m ad\u0131m uygulamal\u0131 \u00f6rneklerle bu temel yetene\u011fi nas\u0131l kazand\u0131raca\u011f\u0131m\u0131z\u0131 ke\u015ffedece\u011fiz. B\u00f6ylece sadece bir metin d\u00fczenleyici de\u011fil, ayn\u0131 zamanda terminal uygulamalar\u0131 geli\u015ftirmenin inceliklerini de \u00f6\u011frenmi\u015f olacaks\u0131n\u0131z. Haydi ba\u015flayal\u0131m ve Go&#8217;nun g\u00fcc\u00fcn\u00fc kullanarak kendi &#8220;yaz\u0131m arkada\u015f\u0131m\u0131z\u0131&#8221; olu\u015ftural\u0131m!<\/p>\n<h2>Terminal Uygulamalar\u0131 ve Go&#8217;nun Rol\u00fc Nedir?<\/h2>\n<p>Terminal tabanl\u0131 uygulamalar, modern GUI uygulamalar\u0131n\u0131n aksine, do\u011frudan komut sat\u0131r\u0131 aray\u00fcz\u00fcnde \u00e7al\u0131\u015f\u0131r ve genellikle bir terminal em\u00fclat\u00f6r\u00fc (\u00f6rne\u011fin iTerm2, Kitty, Windows Terminal) arac\u0131l\u0131\u011f\u0131yla kullan\u0131c\u0131yla etkile\u015fime ge\u00e7er. Bu etkile\u015fim, b\u00fcy\u00fck \u00f6l\u00e7\u00fcde \u00f6zel karakter dizileri olan ANSI ka\u00e7\u0131\u015f kodlar\u0131 kullan\u0131larak sa\u011flan\u0131r. ANSI ka\u00e7\u0131\u015f kodlar\u0131, terminale imlecin konumunu de\u011fi\u015ftirmesi, metin rengini ayarlamas\u0131, ekran\u0131 temizlemesi veya belirli bir alan\u0131 kayd\u0131rmas\u0131 gibi komutlar veren \u00f6zel karakter dizileridir. \u00d6rne\u011fin, imleci ekran\u0131n belirli bir koordinat\u0131na ta\u015f\u0131mak i\u00e7in <code>\\x1b[<SATIR>;<S\u00dcTUN>H<\/code> gibi bir dizi kullan\u0131l\u0131r. Go gibi bir dilde bu kodlar\u0131 do\u011frudan terminale yazarak kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fc kontrol edebiliriz.<\/p>\n<p>Terminal uygulamalar\u0131nda klavye girdilerini i\u015flemek de \u00f6nemli bir ad\u0131md\u0131r. Varsay\u0131lan olarak, terminal genellikle &#8220;yast\u0131kl\u0131&#8221; (buffered) modda \u00e7al\u0131\u015f\u0131r; yani siz Enter tu\u015funa basana kadar yazd\u0131\u011f\u0131n\u0131z karakterler bir tamponda toplan\u0131r ve topluca uygulamaya g\u00f6nderilir. Ancak bir metin d\u00fczenleyici i\u00e7in bu kabul edilemez. Her tu\u015f darbesinin an\u0131nda i\u015flenmesi ve imlecin hemen tepki vermesi gerekir. \u0130\u015fte bu noktada &#8220;ham mod&#8221; (raw mode) devreye girer. Ham modda, terminal klavye girdilerini an\u0131nda uygulamaya iletir, Enter tu\u015funa basma gereklili\u011fini ortadan kald\u0131r\u0131r ve hatta Ctrl+C gibi sinyallerin i\u015fletim sistemi taraf\u0131ndan yorumlanmas\u0131n\u0131 engeller. Go&#8217;da, bu modlar\u0131 y\u00f6netmek i\u00e7in genellikle <code>golang.org\/x\/term<\/code> paketi kullan\u0131l\u0131r. Bu paket, terminalin ham moda ge\u00e7irilmesi ve tekrar eski haline d\u00f6nd\u00fcr\u00fclmesi gibi i\u015flemleri basitle\u015ftiren g\u00fc\u00e7l\u00fc ara\u00e7lar sunar.<\/p>\n<p>Go, bu t\u00fcr d\u00fc\u015f\u00fck seviyeli sistem etkile\u015fimleri i\u00e7in olduk\u00e7a uygun bir dildir. <code>os<\/code> ve <code>syscall<\/code> gibi standart k\u00fct\u00fcphaneleri sayesinde, dosya tan\u0131mlay\u0131c\u0131lar\u0131 (file descriptors) \u00fczerinden do\u011frudan terminalle ileti\u015fim kurabiliriz. Go&#8217;nun e\u015fzamanl\u0131l\u0131k \u00f6zellikleri (goroutine&#8217;ler ve channel&#8217;lar) ise, bir yandan kullan\u0131c\u0131 girdilerini beklerken, di\u011fer yandan ekran\u0131 g\u00fcncelleyebilme veya arka planda ba\u015fka g\u00f6revleri y\u00fcr\u00fctebilme esnekli\u011fi sunar. Bu, \u00f6zellikle karma\u015f\u0131k metin d\u00fczenleyici \u00f6zelliklerinin (\u00f6rne\u011fin s\u00f6z dizimi vurgulama, otomatik tamamlama) performansl\u0131 bir \u015fekilde entegre edilmesi gerekti\u011finde b\u00fcy\u00fck bir avantajd\u0131r. Metin d\u00fczenleyicinin i\u00e7 bellekteki temsili de kritik \u00f6neme sahiptir. Metni sat\u0131r sat\u0131r bir dilim (slice) veya karakter karakter bir dilim olarak tutabiliriz. Unicode deste\u011fi i\u00e7in <code>byte<\/code> dilimleri yerine <code>rune<\/code> dilimleri kullanmak, T\u00fcrk\u00e7e gibi \u00e7ok baytl\u0131 karakterler i\u00e7eren diller i\u00e7in olmazsa olmazd\u0131r. Bu sayede &#8216;\u015f&#8217;, &#8216;\u011f&#8217;, &#8216;\u00fc&#8217; gibi karakterler de do\u011fru \u015fekilde i\u015flenebilir.<\/p>\n<div class=\"tip\">\n      Uzman \u0130pucu: Terminal uygulamalar\u0131nda ekran yenileme s\u0131kl\u0131\u011f\u0131 ve verimlili\u011fi kullan\u0131c\u0131 deneyimi i\u00e7in \u00e7ok \u00f6nemlidir. Ekran\u0131 tamamen temizlemek yerine sadece de\u011fi\u015fen b\u00f6lgeleri yeniden \u00e7izmek, \u00f6zellikle yava\u015f ba\u011flant\u0131larda veya b\u00fcy\u00fck dosyalarda performans\u0131 %30&#8217;a kadar art\u0131rabilir. Bunu sa\u011flamak i\u00e7in imleci do\u011fru konumland\u0131rma ve yaln\u0131zca gerekli karakterleri g\u00f6nderme tekniklerini kullanmal\u0131s\u0131n\u0131z.\n    <\/div>\n<p>\u00d6zetle, Go ile terminal tabanl\u0131 bir metin d\u00fczenleyici geli\u015ftirirken, terminalin temel \u00e7al\u0131\u015fma prensiplerini, ANSI ka\u00e7\u0131\u015f kodlar\u0131n\u0131 ve ham mod kavram\u0131n\u0131 anlamak zorunludur. Go&#8217;nun g\u00fc\u00e7l\u00fc standart k\u00fct\u00fcphaneleri ve e\u015fzamanl\u0131l\u0131k yetenekleri, bu t\u00fcr uygulamalar\u0131 yazmay\u0131 hem keyifli hem de verimli hale getirir. \u015eimdi, bu temel bilgileri kullanarak klavye girdilerini nas\u0131l yakalayaca\u011f\u0131m\u0131za ve imleci nas\u0131l hareket ettirece\u011fimize odaklanabiliriz.<\/p>\n<h2>\u0130mle\u00e7 Hareketi \u0130\u00e7in Go&#8217;da Klavye Girdisi Nas\u0131l Yakalan\u0131r?<\/h2>\n<p>Bir metin d\u00fczenleyicinin can damar\u0131, kullan\u0131c\u0131n\u0131n klavye girdilerine an\u0131nda ve do\u011fru bir \u015fekilde tepki verebilmesidir. Go&#8217;da bu, terminali ham moda alarak ve ard\u0131ndan standart girdiden (stdin) baytlar\u0131 okuyarak ger\u00e7ekle\u015ftirilir. Ancak i\u015f sadece bayt okumakla bitmez; okunan bayt dizilerinin hangi tu\u015fa kar\u015f\u0131l\u0131k geldi\u011fini \u00e7\u00f6z\u00fcmlemek de gereklidir. \u00d6zellikle ok tu\u015flar\u0131, Home, End gibi \u00f6zel tu\u015flar, genellikle birden fazla bayttan olu\u015fan ANSI ka\u00e7\u0131\u015f dizileri olarak g\u00f6nderilir.<\/p>\n<p>\u0130lk ad\u0131m, terminali ham moda almakt\u0131r. Bu, genellikle <code>golang.org\/x\/term<\/code> paketindeki <code>MakeRaw<\/code> fonksiyonu ile yap\u0131l\u0131r. Bu fonksiyon, terminalin mevcut durumunu kaydeder ve onu ham moda ge\u00e7irir. Uygulaman\u0131z sona erdi\u011finde, terminali orijinal durumuna geri d\u00f6nd\u00fcrmek i\u00e7in <code>Restore<\/code> fonksiyonunu kullanman\u0131z \u00f6nemlidir; aksi takdirde terminaliniz tuhaf davranabilir.<\/p>\n<pre><code>\npackage main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"syscall\"\n\n\t\"golang.org\/x\/term\"\n)\n\nfunc main() {\n\t\/\/ Terminalin mevcut durumunu kaydet\n\toldState, err := term.MakeRaw(int(os.Stdin.Fd()))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer term.Restore(int(os.Stdin.Fd()), oldState) \/\/ Uygulama bitti\u011finde terminali eski haline getir\n\n\tfmt.Print(\"\\x1b[2J\") \/\/ Ekran\u0131 temizle\n\tfmt.Print(\"\\x1b[H\")  \/\/ \u0130mleci ba\u015flang\u0131ca ta\u015f\u0131 (sol \u00fcst k\u00f6\u015fe)\n\n\tbuf := make([]byte, 1) \/\/ Tek bayt okumak i\u00e7in tampon\n\tfor {\n\t\tn, err := os.Stdin.Read(buf)\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak \/\/ EOF, stdin kapat\u0131ld\u0131\n\t\t\t}\n\t\t\tpanic(err)\n\t\t}\n\t\tif n > 0 {\n\t\t\tchar := rune(buf[0])\n\t\t\tif char == 'q' || char == 0x03 { \/\/ 'q' veya Ctrl+C (0x03) ile \u00e7\u0131k\u0131\u015f\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t\/\/ Okunan karakteri terminale geri yaz (sadece test ama\u00e7l\u0131)\n\t\t\t\/\/ fmt.Printf(\"Tu\u015f: %q (%d)\\n\", char, char)\n\n\t\t\t\/\/ \u015eimdi \u00f6zel tu\u015flar\u0131 (ok tu\u015flar\u0131 vb.) nas\u0131l yakalayaca\u011f\u0131m\u0131za bakal\u0131m\n\t\t\t\/\/ ANSI ka\u00e7\u0131\u015f dizilerini i\u015flemek daha karma\u015f\u0131kt\u0131r.\n\t\t\t\/\/ \u00d6rne\u011fin, bir ok tu\u015fu genellikle '\\x1b', '[' ve ard\u0131ndan 'A', 'B', 'C' veya 'D' ile ba\u015flar.\n\t\t\tif char == '\\x1b' { \/\/ Esc tu\u015fu veya bir ka\u00e7\u0131\u015f dizisinin ba\u015flang\u0131c\u0131\n\t\t\t\t\/\/ Sonraki baytlar\u0131 okumak i\u00e7in daha b\u00fcy\u00fck bir tampona ihtiya\u00e7 duyabiliriz\n\t\t\t\t\/\/ ve zaman a\u015f\u0131m\u0131 mekanizmas\u0131 uygulamam\u0131z gerekebilir.\n\t\t\t\t\/\/ Bu basit \u00f6rnek i\u00e7in sadece 'Esc'ye bas\u0131ld\u0131\u011f\u0131n\u0131 varsayal\u0131m.\n\t\t\t\tfmt.Print(\"Esc tu\u015funa bas\u0131ld\u0131!\\r\\n\") \/\/ \\r\\n \u00f6nemli\n\t\t\t} else {\n\t\t\t\t\/\/ Normal bir karakter ise ekrana bas\n\t\t\t\tfmt.Printf(\"%c\", char)\n\t\t\t}\n\t\t}\n\t}\n\tfmt.Print(\"\\x1b[H\\x1b[J\") \/\/ \u00c7\u0131kmadan \u00f6nce ekran\u0131 temizle\n}\n\t<\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki kod, tek baytl\u0131k okumalar\u0131 i\u015fleyebilen temel bir yap\u0131y\u0131 g\u00f6steriyor. Ancak ok tu\u015flar\u0131 gibi \u00f6zel tu\u015flar i\u00e7in bu yeterli de\u011fildir. \u00d6rne\u011fin, yukar\u0131 ok tu\u015fu genellikle <code>\\x1b[A<\/code> (ESC, [, A) olarak g\u00f6nderilir. Bu, uygulaman\u0131z\u0131n birden fazla bayt\u0131 h\u0131zl\u0131ca okumas\u0131 ve bunlar\u0131 bir araya getirerek do\u011fru tu\u015fu tan\u0131mas\u0131 gerekti\u011fi anlam\u0131na gelir. Bunu ele alman\u0131n bir yolu, <code>io.Reader<\/code>'dan okurken bir zaman a\u015f\u0131m\u0131 (timeout) mekanizmas\u0131 kullanmak veya gelen baytlar\u0131 bir tamponda biriktirip desen e\u015fle\u015ftirme yapmakt\u0131r. Bu i\u015flem, genellikle \"key event\" (tu\u015f olay\u0131) \u00e7\u00f6z\u00fcc\u00fcleri olarak bilinen ayr\u0131 bir mod\u00fclde yap\u0131l\u0131r.<\/p>\n<p>Girdiyi daha verimli bir \u015fekilde y\u00f6netmek i\u00e7in, tu\u015f bas\u0131mlar\u0131n\u0131 ayr\u0131 bir goroutine'de okuyup bir kanala (channel) g\u00f6nderebilirsiniz. Ana d\u00f6ng\u00fcn\u00fcz bu kanal\u0131 dinler ve gelen tu\u015flara g\u00f6re i\u015flem yapar. Bu yakla\u015f\u0131m, non-blocking (engellemeyen) okumalar i\u00e7in daha esnektir ve gelecekte zaman a\u015f\u0131m\u0131 veya birden fazla girdiyi y\u00f6netme gibi karma\u015f\u0131k senaryolar\u0131 ele alman\u0131za yard\u0131mc\u0131 olur. Go'nun e\u015fzamanl\u0131l\u0131k ilkeleri, metin d\u00fczenleyici gibi interaktif uygulamalar i\u00e7in paha bi\u00e7ilmezdir. Dolay\u0131s\u0131yla, kullan\u0131c\u0131 girdilerini yakalamak, sadece <code>os.Stdin.Read<\/code> \u00e7a\u011f\u0131rmaktan ibaret de\u011fildir; ayn\u0131 zamanda terminalin durumunu y\u00f6netmeyi, \u00f6zel tu\u015f dizilerini \u00e7\u00f6zmeyi ve performans\u0131 maksimize etmek i\u00e7in e\u015fzamanl\u0131l\u0131\u011f\u0131 kullanmay\u0131 da i\u00e7erir.<\/p>\n<h2>Metin D\u00fczenleyici Veri Yap\u0131s\u0131: \u0130mle\u00e7 Konumunu Nerede Saklamal\u0131y\u0131z?<\/h2>\n<p>Bir metin d\u00fczenleyicinin en kritik bile\u015fenlerinden biri, d\u00fczenlenen metni ve imlecin konumunu bellekte nas\u0131l temsil etti\u011fidir. \u0130yi tasarlanm\u0131\u015f bir veri yap\u0131s\u0131, imle\u00e7 hareketlerinin, metin ekleme\/silme i\u015flemlerinin ve genel performans\u0131n temelini olu\u015fturur. Go'da, bu ama\u00e7la genellikle bir <code>struct<\/code> kullan\u0131l\u0131r. Bu <code>struct<\/code>, d\u00fczenleyicinin t\u00fcm state'ini (durumunu) bar\u0131nd\u0131r\u0131r: metin i\u00e7eri\u011fi, imle\u00e7 koordinatlar\u0131, ekran kayd\u0131rma konumu ve di\u011fer ilgili ayarlar.<\/p>\n<p>Metin i\u00e7eri\u011fini temsil etmek i\u00e7in en yayg\u0131n yakla\u015f\u0131mlardan biri, her sat\u0131r\u0131 bir dize (<code>string<\/code>) veya <code>rune<\/code> dilimi (slice of runes) olarak depolayan bir dilim kullanmakt\u0131r. \u00d6rne\u011fin, <code>[][]rune<\/code>, metni sat\u0131r sat\u0131r, her sat\u0131r\u0131 da karakter karakter temsil eder. Neden <code>rune<\/code> kullan\u0131yoruz? \u00c7\u00fcnk\u00fc <code>string<\/code>'ler Go'da salt okunur bayt dilimleridir ve do\u011frudan karakter d\u00fczeyinde manip\u00fclasyonlar\u0131 biraz karma\u015f\u0131k hale getirebilir. Daha da \u00f6nemlisi, T\u00fcrk\u00e7e'deki '\u015f', '\u011f', '\u0131' gibi karakterler veya emoji'ler gibi Unicode karakterler, birden fazla bayt kaplayabilir. <code>rune<\/code>, bu \u00e7ok baytl\u0131 karakterleri tek bir mant\u0131ksal birim olarak temsil eder, b\u00f6ylece imleci \"bir karakter ileri\" ta\u015f\u0131d\u0131\u011f\u0131m\u0131zda ger\u00e7ekten bir Unicode karakter ileri ta\u015f\u0131m\u0131\u015f oluruz, bayt de\u011fil. Bu, \u00e7ok dilli metin d\u00fczenleyicileri i\u00e7in hayati \u00f6nem ta\u015f\u0131r.<\/p>\n<pre><code>\ntype Editor struct {\n\tLines    [][]rune \/\/ Metin i\u00e7eri\u011fi, her sat\u0131r bir rune dilimi\n\tCursorX  int      \/\/ \u0130mlecin mevcut s\u00fctun konumu (0 tabanl\u0131)\n\tCursorY  int      \/\/ \u0130mlecin mevcut sat\u0131r konumu (0 tabanl\u0131)\n\tOffsetX  int      \/\/ Yatay kayd\u0131rma miktar\u0131 (ekran\u0131n sol kenar\u0131ndan ka\u00e7 karakter uzakta oldu\u011fu)\n\tOffsetY  int      \/\/ Dikey kayd\u0131rma miktar\u0131 (ekran\u0131n \u00fcst kenar\u0131ndan ka\u00e7 sat\u0131r uzakta oldu\u011fu)\n\tScreenRows int      \/\/ Terminal ekran\u0131n\u0131n sat\u0131r say\u0131s\u0131\n\tScreenCols int      \/\/ Terminal ekran\u0131n\u0131n s\u00fctun say\u0131s\u0131\n}\n\nfunc NewEditor() *Editor {\n\t\/\/ Ba\u015flang\u0131\u00e7ta bo\u015f bir d\u00fczenleyici\n\treturn &Editor{\n\t\tLines: [][]rune{\n\t\t\t{}, \/\/ \u0130lk bo\u015f sat\u0131r\n\t\t},\n\t\tCursorX:  0,\n\t\tCursorY:  0,\n\t\tOffsetX:  0,\n\t\tOffsetY:  0,\n\t\tScreenRows: 24, \/\/ Varsay\u0131lan de\u011ferler, ger\u00e7ek terminal boyutuna g\u00f6re ayarlanacak\n\t\tScreenCols: 80,\n\t}\n}\n\t<\/pre>\n<p><\/code><\/p>\n<p><code>CursorX<\/code> ve <code>CursorY<\/code> alanlar\u0131, imlecin metin i\u00e7eri\u011fi i\u00e7indeki mant\u0131ksal konumunu temsil eder. <code>CursorY<\/code>, hangi sat\u0131rda oldu\u011fumuzu, <code>CursorX<\/code> ise o sat\u0131r\u0131n hangi karakterinde oldu\u011fumuzu g\u00f6sterir (0 tabanl\u0131 indeksleme kullanarak). Bu koordinatlar, ekran koordinatlar\u0131ndan farkl\u0131d\u0131r; ekran koordinatlar\u0131, metnin ekranda nerede g\u00f6r\u00fcnd\u00fc\u011f\u00fcn\u00fc belirlerken, bu alanlar metnin kendisindeki konumu tutar.<\/p>\n<p><code>OffsetX<\/code> ve <code>OffsetY<\/code> alanlar\u0131, metnin ekran \u00fczerinde nas\u0131l kayd\u0131r\u0131ld\u0131\u011f\u0131n\u0131 y\u00f6netmek i\u00e7in kullan\u0131l\u0131r. E\u011fer metin ekran boyutundan b\u00fcy\u00fckse, kullan\u0131c\u0131n\u0131n metni g\u00f6rebilmesi i\u00e7in ekran\u0131 kayd\u0131rmam\u0131z gerekir. <code>OffsetY<\/code>, dosyan\u0131n ba\u015flang\u0131c\u0131ndan itibaren ka\u00e7 sat\u0131r\u0131n ekran\u0131n \u00fcst kenar\u0131n\u0131n d\u0131\u015f\u0131nda kald\u0131\u011f\u0131n\u0131, <code>OffsetX<\/code> ise sol kenar\u0131n d\u0131\u015f\u0131nda kalan karakter say\u0131s\u0131n\u0131 belirtir. Bu kayd\u0131rma de\u011ferleri, imle\u00e7 hareket etti\u011finde veya metin eklendi\u011finde\/silindi\u011finde dinamik olarak g\u00fcncellenmelidir.<\/p>\n<p><strong>Vaka Analizi: Metin D\u00fczenleyici 'Nano' ve Veri Yap\u0131s\u0131<\/strong><\/p>\n<p>Hafif ve kullan\u0131m\u0131 kolay bir terminal metin d\u00fczenleyicisi olan Nano'nun temel tasar\u0131m felsefesi, karma\u015f\u0131kl\u0131\u011f\u0131 azaltmakt\u0131r. Nano, metni genellikle ba\u011fl\u0131 bir liste (linked list) veya dinamik bir dizi (dynamic array) olarak sat\u0131r sat\u0131r depolar. Her sat\u0131r, kendi i\u00e7inde bir karakter dizisi veya bayt dizisi olabilir. \u0130mlecin konumu, mevcut sat\u0131r d\u00fc\u011f\u00fcm\u00fcne bir i\u015faret\u00e7i ve o sat\u0131r i\u00e7indeki bir indeks ile temsil edilir. Bu yap\u0131, \u00f6zellikle orta boyutlu dosyalar i\u00e7in verimli metin ekleme ve silme i\u015flemleri sa\u011flar. Go'da <code>[][]rune<\/code> yakla\u015f\u0131m\u0131, dinamik dizilere benzer avantajlar sunar ve Go'nun dil \u00f6zellikleriyle do\u011fal bir uyum i\u00e7indedir. Bu sayede, imle\u00e7 hareketlerinde veya metin manip\u00fclasyonlar\u0131nda, ilgili sat\u0131ra h\u0131zl\u0131ca eri\u015febilir ve karakter indekslerini kolayca y\u00f6netebiliriz.<\/p>\n<p>Son olarak, <code>ScreenRows<\/code> ve <code>ScreenCols<\/code> gibi alanlar, terminalin mevcut boyutunu tutar. Bu bilgiler, imleci ekranda do\u011fru konumland\u0131rmak, metni ekran s\u0131n\u0131rlar\u0131 i\u00e7inde g\u00f6stermek ve kayd\u0131rma mant\u0131\u011f\u0131n\u0131 uygulamak i\u00e7in gereklidir. Terminal boyutu de\u011fi\u015fti\u011finde (\u00f6rne\u011fin kullan\u0131c\u0131 terminal penceresini yeniden boyutland\u0131rd\u0131\u011f\u0131nda), bu de\u011ferlerin g\u00fcncellenmesi ve d\u00fczenleyicinin aray\u00fcz\u00fcn\u00fcn yeniden \u00e7izilmesi gerekir. Bu veri yap\u0131s\u0131, Go ile sa\u011flam ve performansl\u0131 bir metin d\u00fczenleyici olu\u015fturman\u0131n temelini olu\u015fturur. \u015eimdi bu yap\u0131y\u0131 kullanarak imleci nas\u0131l hareket ettirece\u011fimizi ad\u0131m ad\u0131m inceleyelim.<\/p>\n<h2>Ad\u0131m Ad\u0131m \u0130mle\u00e7 Hareketini Go ile Nas\u0131l Uygular\u0131z?<\/h2>\n<p>\u0130mle\u00e7 hareketi, metin d\u00fczenleyicinin en temel etkile\u015fimlerinden biridir. Kullan\u0131c\u0131 ok tu\u015flar\u0131na bast\u0131\u011f\u0131nda veya Home\/End gibi \u00f6zel tu\u015flar\u0131 kulland\u0131\u011f\u0131nda, imlecin beklendi\u011fi gibi davranmas\u0131 gerekir. Go'da bu, <code>Editor<\/code> yap\u0131s\u0131ndaki <code>CursorX<\/code> ve <code>CursorY<\/code> de\u011ferlerini g\u00fcncelleyerek ve ard\u0131ndan terminale uygun ANSI ka\u00e7\u0131\u015f kodlar\u0131n\u0131 g\u00f6ndererek ger\u00e7ekle\u015ftirilir. Ancak bu sadece de\u011ferleri art\u0131rmak veya azaltmakla kalmaz; s\u0131n\u0131r kontrolleri, kayd\u0131rma (scrolling) ve sat\u0131r uzunluklar\u0131ndaki farkl\u0131l\u0131klar\u0131 ele almak da hayati \u00f6neme sahiptir.<\/p>\n<h3>Yukar\u0131\/A\u015fa\u011f\u0131 Hareket: Sat\u0131rlar Aras\u0131nda Gezinme Nas\u0131l Yap\u0131l\u0131r?<\/h3>\n<p>\u0130mleci yukar\u0131 veya a\u015fa\u011f\u0131 hareket ettirmek, <code>Editor.CursorY<\/code> alan\u0131n\u0131 de\u011fi\u015ftirmekle ilgilidir. Ancak bu hareketler s\u0131ras\u0131nda dikkate almam\u0131z gereken birka\u00e7 \u00f6nemli nokta vard\u0131r. \u0130lk olarak, imlecin dosyan\u0131n \u00fcst veya alt s\u0131n\u0131rlar\u0131n\u0131n d\u0131\u015f\u0131na \u00e7\u0131kmas\u0131n\u0131 engellemeliyiz. \u0130kinci olarak, farkl\u0131 sat\u0131rlar\u0131n farkl\u0131 uzunluklara sahip olabilece\u011fi ger\u00e7e\u011fini ele almal\u0131y\u0131z.<\/p>\n<p>Bir kullan\u0131c\u0131 yukar\u0131 ok tu\u015funa bast\u0131\u011f\u0131nda, <code>Editor.CursorY<\/code>'yi bir azalt\u0131r\u0131z, ancak <code>CursorY<\/code> s\u0131f\u0131rdan k\u00fc\u00e7\u00fck olamaz. Benzer \u015fekilde, a\u015fa\u011f\u0131 ok tu\u015fu i\u00e7in <code>Editor.CursorY<\/code>'yi bir art\u0131r\u0131r\u0131z, ancak bu de\u011fer toplam sat\u0131r say\u0131s\u0131ndan (<code>len(e.Lines)<\/code>) b\u00fcy\u00fck olamaz. E\u011fer kullan\u0131c\u0131 dosyan\u0131n son sat\u0131r\u0131ndayken a\u015fa\u011f\u0131 ok tu\u015funa basarsa, imle\u00e7 hareket etmemelidir.<\/p>\n<p>Daha karma\u015f\u0131k olan k\u0131s\u0131m, <code>CursorX<\/code>'i ayarlamakt\u0131r. E\u011fer bir sat\u0131rdan daha uzun veya daha k\u0131sa bir sat\u0131ra ge\u00e7iyorsak, <code>CursorX<\/code>'in yeni sat\u0131r\u0131n uzunlu\u011funu a\u015fmamas\u0131n\u0131 sa\u011flamam\u0131z gerekir. \u00d6rne\u011fin, uzun bir sat\u0131r\u0131n sonundayken k\u0131sa bir sat\u0131ra yukar\u0131 \u00e7\u0131karsak, imlecin o k\u0131sa sat\u0131r\u0131n sonuna ayarlanmas\u0131 daha do\u011fal bir kullan\u0131c\u0131 deneyimi sunar:<\/p>\n<pre><code>\nfunc (e *Editor) MoveCursorUp() {\n\tif e.CursorY > 0 {\n\t\te.CursorY--\n\t\te.AdjustCursorX() \/\/ Yeni sat\u0131ra g\u00f6re CursorX'i ayarla\n\t}\n}\n\nfunc (e *Editor) MoveCursorDown() {\n\tif e.CursorY < len(e.Lines)-1 { \/\/ Son sat\u0131r\u0131 a\u015fma\n\t\te.CursorY++\n\t\te.AdjustCursorX() \/\/ Yeni sat\u0131ra g\u00f6re CursorX'i ayarla\n\t}\n}\n\n\/\/ AdjustCursorX imlecin X konumunu mevcut sat\u0131r\u0131n uzunlu\u011funa g\u00f6re ayarlar\nfunc (e *Editor) AdjustCursorX() {\n\tcurrentLineLength := len(e.Lines[e.CursorY])\n\tif e.CursorX > currentLineLength {\n\t\te.CursorX = currentLineLength \/\/ \u0130mleci sat\u0131r\u0131n sonuna ta\u015f\u0131\n\t}\n}\n\t<\/pre>\n<p><\/code><\/p>\n<p>Bu <code>AdjustCursorX<\/code> fonksiyonu, imlecin X konumunun her zaman mevcut sat\u0131r\u0131n ge\u00e7erli bir indeksi oldu\u011fundan emin olur. Bu, kullan\u0131c\u0131n\u0131n uzun bir sat\u0131r\u0131n ortas\u0131ndan daha k\u0131sa bir sat\u0131ra ge\u00e7ip sonra tekrar uzun bir sat\u0131ra d\u00f6nd\u00fc\u011f\u00fcnde imlecin mant\u0131ksal olarak ayn\u0131 karakter konumunda kalmas\u0131n\u0131 sa\u011flamak i\u00e7in de \u00f6nemlidir.<\/p>\n<h3>Sa\u011fa\/Sola Hareket: Karakter Karakter \u0130lerleme Nas\u0131l Sa\u011flan\u0131r?<\/h3>\n<p>\u0130mleci sa\u011fa veya sola hareket ettirmek, <code>Editor.CursorX<\/code> de\u011ferini de\u011fi\u015ftirmekle ilgilidir. Yine burada da s\u0131n\u0131r kontrolleri esast\u0131r. Sa\u011fa hareket ederken, imlecin mevcut sat\u0131r\u0131n sonunu a\u015fmamas\u0131n\u0131 sa\u011flamal\u0131y\u0131z. Sola hareket ederken ise, s\u0131f\u0131r\u0131n alt\u0131na d\u00fc\u015fmemelidir.<\/p>\n<p>Sa\u011fa ok tu\u015funa bas\u0131ld\u0131\u011f\u0131nda, <code>Editor.CursorX<\/code>'i bir art\u0131r\u0131r\u0131z. E\u011fer imle\u00e7 mevcut sat\u0131r\u0131n sonundayken (yani <code>CursorX == len(e.Lines[e.CursorY])<\/code>) sa\u011fa bas\u0131l\u0131rsa, imleci bir sonraki sat\u0131r\u0131n ba\u015f\u0131na (<code>CursorX = 0, CursorY++<\/code>) ta\u015f\u0131mal\u0131y\u0131z, tabii ki dosyan\u0131n son sat\u0131r\u0131nda de\u011filsek. Sola hareket ederken de benzer bir mant\u0131k uygulan\u0131r; e\u011fer imle\u00e7 sat\u0131r ba\u015f\u0131ndayken (<code>CursorX == 0<\/code>) sola bas\u0131l\u0131rsa, bir \u00f6nceki sat\u0131r\u0131n sonuna ge\u00e7ilmelidir.<\/p>\n<pre><code>\nfunc (e *Editor) MoveCursorLeft() {\n\tif e.CursorX > 0 {\n\t\te.CursorX--\n\t} else if e.CursorY > 0 { \/\/ Sat\u0131r ba\u015f\u0131ndaysa bir \u00f6nceki sat\u0131ra ge\u00e7\n\t\te.CursorY--\n\t\te.CursorX = len(e.Lines[e.CursorY]) \/\/ \u00d6nceki sat\u0131r\u0131n sonuna git\n\t}\n}\n\nfunc (e *Editor) MoveCursorRight() {\n\tcurrentLineLength := len(e.Lines[e.CursorY])\n\tif e.CursorX < currentLineLength {\n\t\te.CursorX++\n\t} else if e.CursorY < len(e.Lines)-1 { \/\/ Sat\u0131r sonundaysa bir sonraki sat\u0131ra ge\u00e7\n\t\te.CursorY++\n\t\te.CursorX = 0 \/\/ Sonraki sat\u0131r\u0131n ba\u015f\u0131na git\n\t}\n}\n\t<\/pre>\n<p><\/code><\/p>\n<p>Bu temel hareket fonksiyonlar\u0131, bir metin d\u00fczenleyicide imle\u00e7 y\u00f6netiminin omurgas\u0131n\u0131 olu\u015fturur. Metin ekleme ve silme i\u015flemleri de <code>Lines<\/code> dilimini manip\u00fcle ederken, imlecin do\u011fru konumda kalmas\u0131n\u0131 sa\u011flamak i\u00e7in bu fonksiyonlarla benzer mant\u0131klar kullan\u0131r. Her imle\u00e7 hareketinden sonra, terminale yeni imle\u00e7 konumunu bildiren ANSI ka\u00e7\u0131\u015f kodunu (<code>\\x1b[<SATIR>;<S\u00dcTUN>H<\/code>) g\u00f6ndermeyi unutmamak gerekir. Bu sayede g\u00f6rsel olarak imle\u00e7 ekranda g\u00fcncellenir ve kullan\u0131c\u0131 nerede oldu\u011funu bilir. T\u00fcm bu mant\u0131klar bir araya geldi\u011finde, Go ile olduk\u00e7a duyarl\u0131 ve i\u015flevsel bir metin d\u00fczenleyici deneyimi sunabiliriz.<\/p>\n<h2>Geli\u015fmi\u015f \u0130mle\u00e7 Y\u00f6netimi ve Kullan\u0131c\u0131 Deneyimi \u0130pu\u00e7lar\u0131 Nelerdir?<\/h2>\n<p>Temel imle\u00e7 hareketlerini ger\u00e7ekle\u015ftirdikten sonra, bir metin d\u00fczenleyiciyi ger\u00e7ekten kullan\u0131\u015fl\u0131 hale getiren geli\u015fmi\u015f \u00f6zelliklere ve kullan\u0131c\u0131 deneyimi iyile\u015ftirmelerine odaklanabiliriz. Bu b\u00f6l\u00fcmde, ekran yenileme verimlili\u011fi, kayd\u0131rma mekanizmalar\u0131, performans optimizasyonlar\u0131 ve modern UI yakla\u015f\u0131mlar\u0131n\u0131 inceleyece\u011fiz.<\/p>\n<h3>Ekran Yenileme Verimlili\u011fi ve Kayd\u0131rma<\/h3>\n<p>Bir terminal uygulamas\u0131nda her imle\u00e7 hareketinden veya metin de\u011fi\u015fikli\u011finden sonra t\u00fcm ekran\u0131 yeniden \u00e7izmek, \u00f6zellikle b\u00fcy\u00fck dosyalarda veya yava\u015f ba\u011flant\u0131larda performans\u0131 d\u00fc\u015f\u00fcrebilir. Optimal olan, sadece de\u011fi\u015fen b\u00f6lgeleri veya sat\u0131rlar\u0131 yeniden \u00e7izmektir. Ancak basit bir metin d\u00fczenleyici i\u00e7in, genellikle her de\u011fi\u015fiklikte ekran\u0131 temizleyip (<code>\\x1b[2J<\/code>) t\u00fcm metni ba\u015ftan \u00e7izmek daha kolay bir ba\u015flang\u0131\u00e7 noktas\u0131d\u0131r. Daha geli\u015fmi\u015f yakla\u015f\u0131mlar, \u00f6nceki ekran i\u00e7eri\u011fiyle fark\u0131 (diff) hesaplar ve sadece de\u011fi\u015fen karakterleri veya sat\u0131rlar\u0131 g\u00fcnceller.<\/p>\n<p>Kayd\u0131rma (scrolling), metin i\u00e7eri\u011fi ekran\u0131n boyutunu a\u015ft\u0131\u011f\u0131nda devreye girer. E\u011fer <code>Editor.CursorY<\/code>, ekran\u0131n g\u00f6r\u00fcnen alan\u0131n\u0131n d\u0131\u015f\u0131na \u00e7\u0131karsa, <code>Editor.OffsetY<\/code> de\u011ferini g\u00fcncelleyerek ekran\u0131 yukar\u0131 veya a\u015fa\u011f\u0131 kayd\u0131rmam\u0131z gerekir. \u00d6rne\u011fin, imle\u00e7 ekran\u0131n alt kenar\u0131na ula\u015f\u0131rsa, <code>OffsetY<\/code>'yi art\u0131r\u0131r\u0131z; \u00fcst kenara ula\u015f\u0131rsa <code>OffsetY<\/code>'yi azalt\u0131r\u0131z. Yatay kayd\u0131rma (<code>OffsetX<\/code>) da benzer \u015fekilde \u00e7al\u0131\u015f\u0131r. Bu, kullan\u0131c\u0131n\u0131n metin i\u00e7inde serbest\u00e7e dola\u015fabilmesini ve b\u00fcy\u00fck dosyalar\u0131 rahat\u00e7a d\u00fczenleyebilmesini sa\u011flar.<\/p>\n<pre><code>\nfunc (e *Editor) Scroll() {\n\t\/\/ Dikey kayd\u0131rma kontrol\u00fc\n\tif e.CursorY < e.OffsetY {\n\t\te.OffsetY = e.CursorY\n\t}\n\tif e.CursorY >= e.OffsetY+e.ScreenRows {\n\t\te.OffsetY = e.CursorY - e.ScreenRows + 1\n\t}\n\n\t\/\/ Yatay kayd\u0131rma kontrol\u00fc (basit bir \u00f6rnek)\n\tif e.CursorX < e.OffsetX {\n\t\te.OffsetX = e.CursorX\n\t}\n\tif e.CursorX >= e.OffsetX+e.ScreenCols {\n\t\te.OffsetX = e.CursorX - e.ScreenCols + 1\n\t}\n}\n\nfunc (e *Editor) RefreshScreen() {\n\te.Scroll() \/\/ Kayd\u0131rma mant\u0131\u011f\u0131n\u0131 uygula\n\n\tfmt.Print(\"\\x1b[?25l\") \/\/ \u0130mleci gizle\n\tfmt.Print(\"\\x1b[H\")    \/\/ \u0130mleci ba\u015flang\u0131ca ta\u015f\u0131\n\n\t\/\/ Metni ekrana yaz\n\tfor y := 0; y < e.ScreenRows; y++ {\n\t\tfileRow := e.OffsetY + y\n\t\tif fileRow >= 0 && fileRow < len(e.Lines) {\n\t\t\tline := string(e.Lines[fileRow])\n\t\t\t\/\/ Yatay kayd\u0131rmay\u0131 uygula\n\t\t\tif e.OffsetX < len(line) {\n\t\t\t\tdisplayedLine := line[e.OffsetX:]\n\t\t\t\tif len(displayedLine) > e.ScreenCols {\n\t\t\t\t\tdisplayedLine = displayedLine[:e.ScreenCols]\n\t\t\t\t}\n\t\t\t\tfmt.Print(displayedLine)\n\t\t\t}\n\t\t}\n\t\tfmt.Print(\"\\x1b[K\") \/\/ Sat\u0131r\u0131n kalan\u0131n\u0131 temizle\n\t\tif y < e.ScreenRows-1 {\n\t\t\tfmt.Print(\"\\r\\n\") \/\/ Yeni sat\u0131ra ge\u00e7\n\t\t}\n\t}\n\n\t\/\/ \u0130mleci ger\u00e7ek konumuna ta\u015f\u0131 (g\u00f6r\u00fcn\u00fcr imle\u00e7)\n\tfmt.Printf(\"\\x1b[%d;%dH\", (e.CursorY-e.OffsetY)+1, (e.CursorX-e.OffsetX)+1)\n\tfmt.Print(\"\\x1b[?25h\") \/\/ \u0130mleci g\u00f6ster\n}\n\t<\/pre>\n<p><\/code><\/p>\n<p>Bu <code>RefreshScreen<\/code> fonksiyonu, ekran\u0131 kayd\u0131rma de\u011ferlerine g\u00f6re \u00e7izer ve imleci do\u011fru konuma yerle\u015ftirir. <code>\\x1b[?25l<\/code> imleci gizlerken, <code>\\x1b[?25h<\/code> imleci yeniden g\u00f6sterir. Bu, kullan\u0131c\u0131 ekran\u0131 yenilenirken imlecin titre\u015fimini g\u00f6rmesini engeller.<\/p>\n<h3>Performans Optimizasyonlar\u0131 ve \u0130pu\u00e7lar\u0131<\/h3>\n<ul>\n<li><strong>Sanal Metin (Virtual Text):<\/strong> B\u00fcy\u00fck dosyalarla \u00e7al\u0131\u015f\u0131rken t\u00fcm dosya i\u00e7eri\u011fini bellekte tutmak yerine, sadece g\u00f6r\u00fcnen k\u0131sm\u0131 bellekte tutmak ve diske gerekti\u011finde eri\u015fmek performans\u0131 art\u0131rabilir. Ancak bu, dosya I\/O i\u015flemlerini y\u00f6netmeyi karma\u015f\u0131kla\u015ft\u0131r\u0131r.<\/li>\n<li><strong>Girdiyi Zaman A\u015f\u0131m\u0131yla Okuma:<\/strong> \u00d6zellikle \u00f6zel tu\u015f dizileri (\u00f6rn. Esc tu\u015fuyla ba\u015flayanlar) i\u00e7in, bir sonraki bayt\u0131n gelip gelmedi\u011fini anlamak i\u00e7in k\u0131sa bir zaman a\u015f\u0131m\u0131 (timeout) kullanmak gerekebilir. <code>os.Stdin.Read<\/code> bloklay\u0131c\u0131 oldu\u011fu i\u00e7in, <code>syscall<\/code> paketini veya harici bir k\u00fct\u00fcphaneyi kullanarak non-blocking (engellemeyen) okumalar yapabilir veya ayr\u0131 bir goroutine i\u00e7inde okuyup channel \u00fczerinden iletebiliriz.<\/li>\n<li><strong>ANSI Ka\u00e7\u0131\u015f Kodu K\u00fct\u00fcphaneleri:<\/strong> ANSI kodlar\u0131n\u0131 elle yazmak yerine, <code>github.com\/fatih\/color<\/code> veya <code>github.com\/gookit\/color<\/code> gibi k\u00fct\u00fcphaneler renk ve imle\u00e7 kontrol\u00fcn\u00fc basitle\u015ftirebilir.<\/li>\n<\/ul>\n<div class=\"tip\">\n      Uzman \u0130pucu: Web tabanl\u0131 metin d\u00fczenleyici aray\u00fczleri geli\u015ftirirken mobil uyumluluk kritik \u00f6neme sahiptir. A\u015fa\u011f\u0131daki CSS medya sorgusu \u00f6rne\u011fi, ekran geni\u015fli\u011fi belirli bir e\u015fi\u011fin alt\u0131na d\u00fc\u015ft\u00fc\u011f\u00fcnde d\u00fczenleyicinin yaz\u0131 tipi boyutunu k\u00fc\u00e7\u00fclterek daha iyi bir mobil deneyim sunman\u0131z\u0131 sa\u011flar:<\/p>\n<pre><code class=\"language-css\">\n    @media (max-width: 768px) {\n      .editor-container {\n        font-size: 14px; \/* K\u00fc\u00e7\u00fck ekranlarda yaz\u0131 tipini k\u00fc\u00e7\u00fclt *\/\n      }\n      .line-numbers {\n        display: none; \/* K\u00fc\u00e7\u00fck ekranlarda sat\u0131r numaralar\u0131n\u0131 gizle *\/\n      }\n    }\n      <\/pre>\n<p><\/code><br \/>\n      Bu yakla\u015f\u0131m, kullan\u0131c\u0131lar\u0131n farkl\u0131 cihazlarda da d\u00fczenleyicinizi rahatl\u0131kla kullanabilmesini sa\u011flar. Terminal uygulamalar\u0131 i\u00e7in bu do\u011frudan ge\u00e7erli olmasa da, farkl\u0131 terminal pencere boyutlar\u0131na uyum sa\u011flamak i\u00e7in <code>ScreenRows<\/code> ve <code>ScreenCols<\/code> de\u011ferlerini dinamik olarak alg\u0131lamak ve aray\u00fcz\u00fc buna g\u00f6re yeniden d\u00fczenlemek benzer bir \"uyarlanabilirlik\" prensibini temsil eder. <code>term.GetSize<\/code> fonksiyonu bu ama\u00e7la kullan\u0131labilir.\n    <\/div>\n<h3>Vaka Analizi: Vim ve Emacs'in \u0130mle\u00e7 Felsefesi<\/h3>\n<p>Vim ve Emacs gibi efsanevi metin d\u00fczenleyiciler, imle\u00e7 hareketini sadece karakter veya sat\u0131r baz\u0131nda ele almazlar; kelime, paragraf, kod blo\u011fu veya dosya ba\u015flang\u0131c\u0131\/sonu gibi daha anlamsal birimler \u00fczerinde de hareket etme yetene\u011fi sunarlar. Bu, kullan\u0131c\u0131lar\u0131n metin i\u00e7inde \u00e7ok daha h\u0131zl\u0131 ve verimli bir \u015fekilde gezinmesini sa\u011flar. \u00d6rne\u011fin, Vim'de <code>w<\/code> tu\u015fu bir kelime ileri, <code>b<\/code> bir kelime geri giderken, <code>0<\/code> sat\u0131r ba\u015f\u0131na, <code>$<\/code> sat\u0131r sonuna gider. Bu gibi \"h\u0131zl\u0131 atlama\" \u00f6zellikleri, geli\u015ftiriciler i\u00e7in zaman kazand\u0131r\u0131r ve klavye hakimiyetini art\u0131r\u0131r. Kendi d\u00fczenleyicimizi geli\u015ftirirken, bu t\u00fcr anlamsal hareketleri (\u00f6rne\u011fin bo\u015fluklara bakarak kelime s\u0131n\u0131rlar\u0131n\u0131 belirleme) eklemeyi d\u00fc\u015f\u00fcnebiliriz. Bu t\u00fcr \u00f6zellikler, metin d\u00fczenleyicinizi sadece temel bir ara\u00e7tan \u00f6teye ta\u015f\u0131yarak ger\u00e7ek bir verimlilik arac\u0131 haline getirebilir.<\/p>\n<p>Geli\u015fmi\u015f imle\u00e7 y\u00f6netimi ve kullan\u0131c\u0131 deneyimi iyile\u015ftirmeleri, bir metin d\u00fczenleyiciyi sadece \u00e7al\u0131\u015fan bir uygulamadan, keyifli ve verimli bir araca d\u00f6n\u00fc\u015ft\u00fcr\u00fcr. Go'nun esnekli\u011fi ve performans\u0131, bu t\u00fcr karma\u015f\u0131k \u00f6zellikleri uygulamak i\u00e7in sa\u011flam bir temel sunar.<\/p>\n<h2>Sonu\u00e7 ve S\u0131k\u00e7a Sorulan Sorular<\/h2>\n<p>Bu kapsaml\u0131 makale boyunca, Go programlama diliyle temel bir terminal tabanl\u0131 metin d\u00fczenleyici olu\u015fturman\u0131n \u00f6nemli bir ad\u0131m\u0131 olan imle\u00e7 y\u00f6netimini detayl\u0131 bir \u015fekilde inceledik. \u00d6ncelikle, kendi metin d\u00fczenleyicinizi yazman\u0131n arkas\u0131ndaki motivasyonlar\u0131 ve Go'nun bu t\u00fcr bir proje i\u00e7in neden ideal bir se\u00e7im oldu\u011funu ele ald\u0131k. Ard\u0131ndan, terminal uygulamalar\u0131n\u0131n temel \u00e7al\u0131\u015fma prensiplerine, ANSI ka\u00e7\u0131\u015f kodlar\u0131n\u0131n g\u00fcc\u00fcne ve Go'nun ham mod girdisi y\u00f6netimi yeteneklerine derinlemesine dald\u0131k. Metin d\u00fczenleyicinin bellekteki temsili i\u00e7in uygun veri yap\u0131lar\u0131n\u0131, \u00f6zellikle Unicode karakterler i\u00e7in <code>rune<\/code> kullan\u0131m\u0131n\u0131n \u00f6nemini vurgulayarak tasarlad\u0131k.<\/p>\n<p>Uygulamal\u0131 b\u00f6l\u00fcmde, klavye girdilerini nas\u0131l yakalayaca\u011f\u0131m\u0131z\u0131 g\u00f6sterdik ve imlecin yukar\u0131, a\u015fa\u011f\u0131, sa\u011fa ve sola hareketini ad\u0131m ad\u0131m kod \u00f6rnekleriyle a\u00e7\u0131klad\u0131k. Bu hareketler s\u0131ras\u0131nda sat\u0131r uzunluklar\u0131na ve dosya s\u0131n\u0131rlar\u0131na dikkat etmenin \u00f6nemini vurgulad\u0131k. Son olarak, ekran yenileme verimlili\u011fi, kayd\u0131rma mekanizmalar\u0131, performans optimizasyonlar\u0131 ve Vim\/Emacs gibi geli\u015fmi\u015f d\u00fczenleyicilerin imle\u00e7 felsefesinden ilham alan kullan\u0131c\u0131 deneyimi ipu\u00e7lar\u0131 gibi ileri d\u00fczey konulara de\u011findik. Ayr\u0131ca, terminal uygulamalar\u0131 i\u00e7in do\u011frudan ge\u00e7erli olmasa da, modern web tabanl\u0131 aray\u00fczlerde mobil uyumlulu\u011fun bir \u00f6rne\u011fi olarak CSS medya sorgular\u0131na da k\u0131sa bir bak\u0131\u015f att\u0131k.<\/p>\n<p>Go ile bir metin d\u00fczenleyici in\u015fa etmek, sadece programlama becerilerinizi geli\u015ftirmekle kalmaz, ayn\u0131 zamanda i\u015fletim sistemleriyle etkile\u015fimden kullan\u0131c\u0131 aray\u00fcz\u00fc tasar\u0131m\u0131na kadar bir\u00e7ok alanda de\u011ferli bilgiler edinmenizi sa\u011flar. Bu proje, Go'nun sadeli\u011fini, performans\u0131n\u0131 ve e\u015fzamanl\u0131l\u0131k yeteneklerini pratik bir ba\u011flamda deneyimlemek i\u00e7in m\u00fckemmel bir f\u0131rsatt\u0131r. Unutmay\u0131n, her b\u00fcy\u00fck yaz\u0131l\u0131m projesi, k\u00fc\u00e7\u00fck, y\u00f6netilebilir ad\u0131mlarla ba\u015flar. \u0130mle\u00e7 hareketini ustaca y\u00f6netmek, bu yolculukta ataca\u011f\u0131n\u0131z ilk ve en kritik ad\u0131mlardan biridir. Bu temelleri kullanarak, kendi benzersiz ve g\u00fc\u00e7l\u00fc metin d\u00fczenleyicinizi geli\u015ftirmeye devam edebilirsiniz. Ba\u015far\u0131lar!<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<ul>\n<li>\n            <strong>Go ile terminal tabanl\u0131 bir metin d\u00fczenleyici olu\u015fturmak neden iyi bir fikir?<\/strong><\/p>\n<p>Go, g\u00fc\u00e7l\u00fc e\u015fzamanl\u0131l\u0131k deste\u011fi, y\u00fcksek performans ve basit s\u00f6zdizimi sayesinde terminal tabanl\u0131 uygulamalar (TUI) i\u00e7in idealdir. Go ile yaz\u0131lan uygulamalar genellikle h\u0131zl\u0131 \u00e7al\u0131\u015f\u0131r ve tek bir derlenmi\u015f ikili dosya olarak da\u011f\u0131t\u0131labilir, bu da \u00e7apraz platform uyumlulu\u011fu ve da\u011f\u0131t\u0131m\u0131 kolayla\u015ft\u0131r\u0131r. Ayr\u0131ca, d\u00fc\u015f\u00fck seviyeli sistem etkile\u015fimlerine olanak tan\u0131yarak terminalin t\u00fcm \u00f6zelliklerini kullanman\u0131za izin verir.<\/p>\n<\/li>\n<li>\n            <strong>\u0130mle\u00e7 hareketini optimize etmek i\u00e7in hangi teknikler kullan\u0131labilir?<\/strong><\/p>\n<p>\u0130mle\u00e7 hareketini optimize etmek i\u00e7in, sadece imle\u00e7 hareket etti\u011finde ekran\u0131 tamamen yeniden \u00e7izmek yerine, de\u011fi\u015fen b\u00f6lgeleri veya karakterleri hedefleyerek k\u0131smi yenileme yapabilirsiniz. B\u00fcy\u00fck dosyalar i\u00e7in t\u00fcm metni bellekte tutmak yerine, dosyan\u0131n sadece g\u00f6r\u00fcnen k\u0131sm\u0131n\u0131 y\u00fcklemek (sanal metin) performans\u0131 art\u0131rabilir. Ayr\u0131ca, klavye girdilerini okurken non-blocking (engellemeyen) y\u00f6ntemler veya ayr\u0131 goroutine'ler kullanmak, uygulaman\u0131n daha duyarl\u0131 olmas\u0131n\u0131 sa\u011flar.<\/p>\n<\/li>\n<li>\n            <strong>\u00c7ok dilli metinlerde imle\u00e7 y\u00f6netimi nas\u0131l yap\u0131l\u0131r?<\/strong><\/p>\n<p>\u00c7ok dilli metinlerde (T\u00fcrk\u00e7e, Japonca, Korece vb. gibi Unicode karakterler i\u00e7eren diller), metni bayt dilimleri (<code>[]byte<\/code>) yerine <code>rune<\/code> dilimleri (<code>[]rune<\/code>) olarak saklamak kritik \u00f6neme sahiptir. <code>rune<\/code>, tek bir mant\u0131ksal Unicode karakteri temsil ederken, baytlar birden fazla baytl\u0131k karakterlerin yanl\u0131\u015f say\u0131lmas\u0131na neden olabilir. <code>rune<\/code> kullanarak imleci her zaman tek bir karakter ileri veya geri ta\u015f\u0131d\u0131\u011f\u0131n\u0131zdan emin olabilirsiniz.<\/p>\n<\/li>\n<li>\n            <strong>Performans sorunlar\u0131 ya\u015farsam ne yapmal\u0131y\u0131m?<\/strong><\/p>\n<p>Performans sorunlar\u0131 ya\u015f\u0131yorsan\u0131z, \u00f6ncelikle kodunuzda profil olu\u015fturma (profiling) ara\u00e7lar\u0131 kullanarak darbo\u011fazlar\u0131 belirleyin. Ekran yenileme s\u0131kl\u0131\u011f\u0131n\u0131 ve miktar\u0131n\u0131 azalt\u0131n (sadece de\u011fi\u015fen alanlar\u0131 \u00e7izmeye odaklan\u0131n). Girdi i\u015fleme d\u00f6ng\u00fcn\u00fcz\u00fc optimize edin; gereksiz bellek tahsisinden ka\u00e7\u0131n\u0131n. B\u00fcy\u00fck dosyalar i\u00e7in sanal metin yakla\u015f\u0131m\u0131n\u0131 d\u00fc\u015f\u00fcn\u00fcn. Go'nun yerle\u015fik ara\u00e7lar\u0131 (<code>pprof<\/code> gibi) performans analizinde size \u00e7ok yard\u0131mc\u0131 olacakt\u0131r.<\/p>\n<\/li>\n<li>\n            <strong>\u0130mlecin rengini veya stilini de\u011fi\u015ftirebilir miyim?<\/strong><\/p>\n<p>Evet, imlecin rengini veya stilini (\u00f6rne\u011fin blok, alt \u00e7izgi, dikey \u00e7izgi) terminale ANSI ka\u00e7\u0131\u015f kodlar\u0131 g\u00f6ndererek de\u011fi\u015ftirebilirsiniz. \u00d6rne\u011fin, <code>\\x1b[?2J<\/code> veya <code>\\x1b[?6u<\/code> gibi kodlar modern terminallerde imle\u00e7 stilini kontrol etmenizi sa\u011flar. Renkler i\u00e7inse, metin rengini ayarlarken kullan\u0131lan <code>\\x1b[38;2;<R>;<G>;<B>m<\/code> gibi kodlar\u0131 imle\u00e7le birlikte kullanabilirsiniz. Ancak, t\u00fcm terminaller bu \u00f6zelliklerin tamam\u0131n\u0131 desteklemeyebilir.<\/p>\n<\/li>\n<\/ul>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Go programlama diliyle kendi metin d\u00fczenleyicinizi geli\u015ftirirken imle\u00e7 y\u00f6netimi nas\u0131l yap\u0131l\u0131r? Bu kapsaml\u0131 rehberde, klavye girdilerini i\u015fleyerek imleci&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-34088","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Go ile Metin D\u00fczenleyici Olu\u015fturma: \u0130mleci Hareket Ettirme Sanat\u0131<\/title>\n<meta name=\"description\" content=\"Go programlama diliyle kendi metin d\u00fczenleyicinizi geli\u015ftirirken imle\u00e7 y\u00f6netimi nas\u0131l yap\u0131l\u0131r? Bu kapsaml\u0131 rehberde, klavye girdilerini i\u015fleyerek imleci sorunsuz bir \u015fekilde hareket ettirme tekniklerini ad\u0131m ad\u0131m \u00f6\u011freneceksiniz.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Go ile Metin D\u00fczenleyici Olu\u015fturma: \u0130mleci Hareket Ettirme Sanat\u0131\" \/>\n<meta property=\"og:description\" content=\"Go programlama diliyle kendi metin d\u00fczenleyicinizi geli\u015ftirirken imle\u00e7 y\u00f6netimi nas\u0131l yap\u0131l\u0131r? Bu kapsaml\u0131 rehberde, klavye girdilerini i\u015fleyerek imleci sorunsuz bir \u015fekilde hareket ettirme tekniklerini ad\u0131m ad\u0131m \u00f6\u011freneceksiniz.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-10T23:01:06+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"25 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Go ile Metin D\u00fczenleyici Olu\u015fturma: \u0130mleci Hareket Ettirme Sanat\u0131\",\"datePublished\":\"2025-11-10T23:01:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/\"},\"wordCount\":4245,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/\",\"name\":\"Go ile Metin D\u00fczenleyici Olu\u015fturma: \u0130mleci Hareket Ettirme Sanat\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-11-10T23:01:06+00:00\",\"description\":\"Go programlama diliyle kendi metin d\u00fczenleyicinizi geli\u015ftirirken imle\u00e7 y\u00f6netimi nas\u0131l yap\u0131l\u0131r? Bu kapsaml\u0131 rehberde, klavye girdilerini i\u015fleyerek imleci sorunsuz bir \u015fekilde hareket ettirme tekniklerini ad\u0131m ad\u0131m \u00f6\u011freneceksiniz.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Go ile Metin D\u00fczenleyici Olu\u015fturma: \u0130mleci Hareket Ettirme Sanat\u0131\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Go ile Metin D\u00fczenleyici Olu\u015fturma: \u0130mleci Hareket Ettirme Sanat\u0131","description":"Go programlama diliyle kendi metin d\u00fczenleyicinizi geli\u015ftirirken imle\u00e7 y\u00f6netimi nas\u0131l yap\u0131l\u0131r? Bu kapsaml\u0131 rehberde, klavye girdilerini i\u015fleyerek imleci sorunsuz bir \u015fekilde hareket ettirme tekniklerini ad\u0131m ad\u0131m \u00f6\u011freneceksiniz.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/","og_locale":"tr_TR","og_type":"article","og_title":"Go ile Metin D\u00fczenleyici Olu\u015fturma: \u0130mleci Hareket Ettirme Sanat\u0131","og_description":"Go programlama diliyle kendi metin d\u00fczenleyicinizi geli\u015ftirirken imle\u00e7 y\u00f6netimi nas\u0131l yap\u0131l\u0131r? Bu kapsaml\u0131 rehberde, klavye girdilerini i\u015fleyerek imleci sorunsuz bir \u015fekilde hareket ettirme tekniklerini ad\u0131m ad\u0131m \u00f6\u011freneceksiniz.","og_url":"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-11-10T23:01:06+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"25 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Go ile Metin D\u00fczenleyici Olu\u015fturma: \u0130mleci Hareket Ettirme Sanat\u0131","datePublished":"2025-11-10T23:01:06+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/"},"wordCount":4245,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/","url":"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/","name":"Go ile Metin D\u00fczenleyici Olu\u015fturma: \u0130mleci Hareket Ettirme Sanat\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-11-10T23:01:06+00:00","description":"Go programlama diliyle kendi metin d\u00fczenleyicinizi geli\u015ftirirken imle\u00e7 y\u00f6netimi nas\u0131l yap\u0131l\u0131r? Bu kapsaml\u0131 rehberde, klavye girdilerini i\u015fleyerek imleci sorunsuz bir \u015fekilde hareket ettirme tekniklerini ad\u0131m ad\u0131m \u00f6\u011freneceksiniz.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/go-ile-metin-duzenleyici-olusturma-imleci-hareket-ettirme-sanati\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Go ile Metin D\u00fczenleyici Olu\u015fturma: \u0130mleci Hareket Ettirme Sanat\u0131"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34088","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=34088"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34088\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=34088"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=34088"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=34088"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}