         
         let selectedRanges = textView.selectedRanges.map(\.rangeValue)
         
-        // repeat while dragging
-        self.draggingTimer = .scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(selectLines),
-                                             userInfo: DraggingInfo(index: index, selectedRanges: selectedRanges),
-                                             repeats: true)
-        self.draggingTimer?.fire()  // for single click event
+        self.draggingInfo = DraggingInfo(index: index, selectedRanges: selectedRanges)
+        
+        // for single click event
+        self.selectLines(with: event)
+    }
+    
+    
+    /// select lines while dragging event
+    override func mouseDragged(with event: NSEvent) {
+        
+        self.selectLines(with: event)
     }
     
     
     /// end selecting correspondent lines in text view with drag event
     override func mouseUp(with event: NSEvent) {
         
-        self.draggingTimer?.invalidate()
+        self.draggingInfo = nil
     }
     
     

    private var opacityObserver: AnyCancellable?
    private var textViewSubscriptions: Set<AnyCancellable> = []
    
    private weak var draggingTimer: Timer?
    
    @IBOutlet private weak var textView: NSTextView? {
        

        }
        
        // with Shift key (expand selection)
        if event.modifierFlags.contains(.shift) {
            let selectedRange = textView.selectedRange
            if selectedRange.contains(currentIndex) {  // reduce
                let inUpperSelection = (currentIndex - selectedRange.location) < selectedRange.length / 2
