Değiştirme komutu hangi editörde ctrl-h olarak tanımlı? Ya da genelde bu kısayola mı atanır? Bilmediğimden soruyorum; bu kısayolu kullanmadım hiç. Her şekilde varsayılan klavye kısayolları için tartışılması gerek; çoğunluğun aşina olacağı kısayollar olmalı. Tabii değiştirme olanağı da sağlanmalı. Siz yaptığınız değişiklikleri ilgili veri havuzuna çekme isteği olarak gönderin, orada tartışırız.
Eğer uygulamayı, uygulamayı geliştirmek için kullanıyorsanız katılıyorum. Değilse; arama, farklı kaydetme, değişikliği başlıkta yıldız ile bildirme, çıkışta kaydedilmemiş dosya için uyarı gösterme, vb. daha öncelikli konular var.
Bunlar IDLE ve vs code de ortak özellikler. Vs code de bu kısayollar değiştirilebiliyor.
Kısayollar için bir pr yollayım size.
Şu an uygulama geliştirilme aşamasında olduğu için diğer sorunlar çok da dikkat çekmiyor. Ancak python dilinde girintileme olmazsa olmaz. Kıvrandırıyor. Acı çektiriyor.
Acaba girintileme için aşağıdaki kodlar işinize yarar mı?
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
import tkinter as tk
root = tk.Tk()
text = tk.Text(master=root)
text.pack()
# Kısayol kombinasyonlarını kontrol etmek için bir liste tanımlanır.
shortcuts = []
# ctrl tuşuna basınca başlayan zaman sayacı
start = 0
def indent(event):
global shortcuts, start
# İmlecin satır değeri bir değişkene atanır.
row = text.index("insert").split(".")[0]
# İmleçten bir önceki satır ile imlecin bulunduğu satır
# arasında kalan karakter dizileri kaydedilir.
line = text.get("{}.0".format(int(row) - 1), "{}.0".format(row))
# Eğer kullanıcı "enter" tuşuna basarsa:
if event.keysym == "Return":
# Eğer bir önceki satır ":" işaretiyle bitmişse:
if line[-2] == ":":
# Bir önceki satırdaki girintelemeyi say
count = line.count(" " * 4)
# Girintileme sayısının bir fazlası kadarını girintiyi ekle.
# (Girintisi 0 olan bir satırda ':' işareti kullandıktan sonra,
# bir sonraki satırda tek bir girinti eklemek için
# count'ı 1 ile toplamamız gerek.)
text.insert("insert", " " * 4 * (count + 1))
elif event.keysym == "Control_L": # Eğer kullanıcı sol ctrl tuşuna basarsa:
# sayacı çalıştır.
start = time.time()
# Eğer "Control_L" shortcuts listesinde değilse,
if event.keysym not in shortcuts:
# shortcuts listesine ekle.
shortcuts.append(event.keysym)
# Eğer kullanıcı "f" tuşuna basarsa:
elif event.keysym == "f":
# Eğer "Control_L" shortcuts listesindeyse:
if "Control_L" in shortcuts:
# Eğer geçen zaman 0.5 saniyeden azsa:
if time.time() - start < 0.5:
# Bir önceki satırdaki girintilemeyi say
count = line.count(" " * 4)
# Ve girinti sayısı kadar girintiyi widgete ekle.
text.insert("insert", " " * 4 * count)
# Sayacı sıfırla.
start = 0
# Listeyi sıfırla.
shortcuts = []
text.bind("<KeyRelease>", indent)
root.mainloop()
Şöyle anlatmaya çalışayım hocam: Ekran görüntüsünde gördüğünüz gibi, bir satır eğer “:” karakteriyle bitmişse ve kullanıcı enter tuşuna basarsa bir sonraki satırda bir girinti oluşturulur.
# Diyelim şöyle bir şey yazdık
def f():
def g(): # Bu satırın girintisi otomatik olarak oluşturulur.
def h(): # Bu satırın girintisi otomatik olarak oluşturulur.
# Bu satırın girintisi otomatik olarak oluşturulur.
# Ama bir alt satır olan bu satırı bir üst satırdaki girintiden başlatmak
# için ctrl + f tuşuna basarız. Ve aşağıdaki gibi bir sonucu hiç
# space tuşuna basmadan hızlıca elde ederiz.
# Bunun gibi.
Özetle ctrl + f özelliği biraz tab tuşunun yaptığına benziyor. Ancak tab gibi 8 tane boşluk koymak yerine, bir üst satırdaki girintiyi hesaplıyor. Alt satıra o girintiyi ekliyor.
Bir de şöyle bir özellik eklenebilir. Öyle bir tuş kombinasyonu tanımlanır ki, bir adet girinti silinir. Girinti ekleme işleminin tersi bir işlem gibi düşünün. Yani her zaman kaldığımız satırdaki girintiden devam etmeyebiliriz değil mi? Şunun gibi:
def f():
def g():
if a:
...
else b: # İşte bu satırı tekrar if'in girintisine tuş kombinasyonu ile getirebiliriz.
# ctrl + f'e basınca if blokunun altındaki girinti alt satıra eklenecek.
# Ama sonra başka bir özel tuş kombinasyonu ile else'in girintisi 1 kademe düşürülebilir.
# Böylece girintiyi ayarlamak için backspace tuşuna basmak zorunda kalmayız.
Not: Bu arada “Control_L”, sol ctrl tuşu demek, Control_Left’in kısaltılmışı.
Binding ile bu kombinasyonu atayabilirdiniz: wigdet.bind("<Control-KeyPress-f>",indent)
Yanlış hatırlamıyorsam böyle bir şeydi.
Şu linkteki editörde kullanılıyor:
@hasser, o da olur, bence fark etmez.
Başka ctrl tuş kombinasyoları oluşturabiliriz, örneğin aşağıdaki gibi.
Yukarıda bahsettiğim 1 adet girintiyi (4 adet boşluğu) silmeye yarayan bir koşul mesela:
Bu da ctrl + g tuşuna basınca aktif olacak koşul.
elif event.keysym == "g":
# Eğer "Control_L" shortcuts listesindeyse:
if "Control_L" in shortcuts:
# Eğer geçen zaman 0.5 saniyeden azsa:
if time.time() - start < 0.5:
text.delete("{}.{}".format(row, int(col) - 4), "{}.{}".format(row, col))
# Sayacı sıfırla.
start = 0
# Listeyi sıfırla.
shortcuts = []
Ctrl+F, genelde arama kutusunu açmak için kullanılan bir kısayol. Sanırım siz “Format” anlamında kullanmışsınız. Tabii ki önemli bir durum değil, farklı bir kısayol bulunabilir.
Hem Ctrl+F, hem de bunun için şunu diyebilirim: Kullanıcı, kısayolları, olabildiğince, bilmek zorunda kalmamalı. Ki bilmek ayrı, uygulamak ayrıdır. Kullanıcıların, çok bilindik olmayan kısayollara alışmak için çaba harcayacaklarını sanmam. Bir de buradaki durum için şöyle bir şey var: Genelde sekmeler bir dosya içindeki sekmeler 3-5 sekmeyi geçmez. Bu durumda kullanıcı genelde en fazla 2-3 kez Backspace tuşuna basarak istediğini elde edebilir. Bir kısayol tanımlasak bu kısayolun kendisi zaten 2 kez basmaya denk gelecek. Yani bana göre çok iyi bir kazanımı yok burada kısayolun.
“Control_L” yerine “Control” kullanmak daha iyi değil mi her yerde? Yani sol ve sağdaki Ctrl tuşları ile bir başka aynı tuşun kombinasyonuna farklı bir görev verildiği bir durum olabilir mi?
Tkinter’da olayların(event) bağlanması(bind) ile ilgili yeni keşfettiğim bir şey var. Örneğin şöyle bir kodumuz var diyelim:
text.bind("<Control-KeyPress-f>", ctrl_f)
Bu durumda Caps Lock açıkken Ctrl+F’ye bastığınızda hiçbir şey olmaz. Çünkü siz Ctrl+f’yi bağladınız, Ctrl+F’yi değil! Biliyorum, şaşırtıcı ama Tkinter’da durum tam olarak bu. Çözümü ise basit:
Evet, katılıyorum, önemli bir durum değil, farklı bir kısayol bulunabilir.
O zaman bunu bir düzenlemeye çalışayım. ctrl + f’e gerek kalmadan, “enter” tuşuna basıldığında, alttaki satır, üstteki satırın girintisine otomatik olarak gelsin.
Yani ctrl_f fonksiyonunu kaldırıp indent fonksiyonunu şu şekilde yazabiliriz (tıpkı PyCharm’daki gibi.):
Evet keysym için de benzer bir yol izleyebiliriz. Ama aşağıdaki kodlarda, keysym sadece bir yerde kullanıldı, “Enter” tuşuna basıldığında yapılacak olan işlemde.
Bu arada ctrl + f’in yerine yeni bir girinti tanıma işlemi için ve caps lock durumu için bir düzenleme yaptım.
Kodları şöyle değiştirdim:
class A:
def __init__(self):
self. x = None
for i in range(10):
print("gjkgjkgj")
# Şimdi bu satırdayken, ctrl + f'e bassak;
# (Veya yeni düzenlemeye göre print("gjkgjkgj") fonksiyonundan sonra
# sadece enter tuşuna bassak)
# İmleç bu sütun konumuna otomatik olarak gelir.
# Ama diyelim bu yorumun başladığı sütuna gelmek istiyorum.
12345678
# Toplam 8 tane boşluk var. İşte bu 8 boşluğu
# ctrl + g'ye iki kere basarak silebiliriz.
# Öbür türlü 8 kere silme tuşuna basmak gerekecek.
# Üstelik boşluk sayısı 8 değil de 12 veya 16 da olabilir.
# Mesela alt alta yazılmış for döngülerini olduğunu düşünelim.
# Her bir for blokunun içinde if durumları olabilir.
Veya bu son bahsettiğim ile ilgili şöyle bir şey de yapılabilir herhalde, backspace tuşuna basıldığında, şayet soldaki karakter girintiden oluşuyorsa, 4 adet boşluk silinebilir, şayet soldaki karakter normal bir karakter ise tek bir karakter silme işlemi tanımlanabilir. Tıpkı PyCharm’daki gibi, bir denemek lazım.
Tamam, sizin dediğiniz gibi yaptım, ctrl + f ve ctrl + g tuş kombinasyonlarını kaldırdım, yerine girinti durumuna göre çalışan bir girinti ekleme ve girinti silme işlemi tanımladım. Çalışma şekli PyCharm’daki girintilerin çalışma şekline benziyor.
Programı çalıştırıp Enter ve BackSpace tuşlarının nasıl çalıştığına bir bakın isterseniz.
README dosyasında uygulamayı çalıştırma komutlarını ekledim. Şimdi daha sade oldu. Sıkıntı için kusura bakmayın, doğru paket yapısını bulmaya çalışırken sık sık dizin yapısını değiştirmek durumunda kaldım.
Yok, olmazdı. Uygulamalar büyüdükçe tek dosya içinde geliştirmesi giderek zorlaşıyor. Ki bu uygulamanın büyüme kapasitesi yüksek. Şimdiden önlem alınıp modüler bir şekilde geliştirmeye devam edilmezse, ileride bu baş ağrısına sebep olur. Hatta bu modülerliği kurmak için şimdi harcanan zamandan çok daha fazlası hata ayıklamaya gitmeye başlar.
Aynen öyle. Girintileme olan yerleri bulmak kolay: Eğer bir satırda boşluk karakterlerinden önce bir kod yoksa, o satırdaki boşluk karakterleri girintilemedir.
Windows kullanmıyorsunuz sanırım. GNU/Linux’te .ico dosyaları ile ilgili sorun çıktığını okumuştum. Belki bu konuda da bir şeyler yapabilirsiniz, GNU/Linux bir işletim sistemine erişimim olmadığı için ben pek bir şey yapamıyorum.
O sırada kullanmıyordum evet.
Yok sorun değil, ilgili satırı yoruma aldım ve çalıştırdım.
Bu arada girinti ekleme işlemini programa ekledim ve PR gönderdim ama sanırım bir hata veriyor.