Dateisuche

Alternatives Datei-Suchfenster für Linux – hilfreich für den, bei dessen Lieblings-Dateifenster die Suche zu unbequem ist. Verwendet den Befehl locate.

Zum Öffnen dient als Voreinstellung das Programm open. Es kann mit einem beliebigen ausführbaren Programm überschrieben werden.


#!/usr/bin/tclsh

package require Tk

wm title . Dateisuche

pack [entry .searchString] -expand no -fill x
pack [text .searchResult -height 5 -wrap none] -expand yes -fill both
pack [entry .run] -expand no -fill x

proc cursorWatch {} {
  foreach win [concat . [winfo children .]] {
    dict set pointer $win [$win cget -cursor]
    $win configure -cursor watch
  }
  update
  dict for {win cursor} $pointer {
    $win configure -cursor $cursor
  }
}

proc searchFiles {{pattern *}} {
  set home [file normalize ~]/
  if {[regexp {[[:upper:]]} $pattern]} then {
    set result [exec find $home -name $pattern]
  } else {
    set result [exec locate -i $home*$pattern]
  }
  regsub -all (^|\n)$home $result {\1}
}

bind .searchString <Key-Return> {
  cursorWatch
  catch {
    .searchResult replace 1.0 end [searchFiles [.searchString get]]
  }
}

bind .searchResult <Double-Button-1> {
  %W tag remove sel 1.0 end
  %W tag add sel "insert linestart" "insert lineend"
  break
}

event add <<Invoke>> <Triple-Button-1> <Control-Button-1>

bind .searchResult <<Invoke>> {
  %W tag remove sel 1.0 end
  %W mark set insert @%x,%y
  %W tag add sel "insert linestart" "insert lineend"
  exec open [%W get "insert linestart" "insert lineend"] &
  break
}

bind .run <Key-Return> {
  exec {*}[.run get] &
}

bind .run <<Paste>> {
  if {[catch {clipboard get}]} break
  %W delete 0 end
  %W insert 0 [list open [string trim [clipboard get]]]
  break
}

menu .context -tearoff no
.context add command -label Copy -command {
  event generate [focus] <<Copy>>
}

.context add command -label Paste -command {
  event generate [focus] <<Paste>>
}

bind .searchResult <Button-3><ButtonRelease> {
  focus %W
  tk_popup .context %X %Y 0
}
bind .run <Button-3><ButtonRelease> {
  focus %W
  tk_popup .context %X %Y 1
}

Installation:

Gebrauchsanweisung:

Suchfenster


Nachtrag – Kommentator Aureolus weist die Möglichkeit hin, das Script im Desktop zu verankern.

Nachtrag 2 – Wenn ein Programm open nicht in der Distribution enthalten ist – etwa bei meinem Linux Mint – dann ist es für den Adepten eigentlich ein Spaziergang, ein solches Script im Suchpfad selbst zu erstellen.

Nachtrag 3 – auf meinem neuen Huawei Matebook und LinuxMint Xfce4 funktioniert das Kommando locate nicht wie gewohnt. Dafür habe ich eine Version mit dem Kommando find geschrieben.


#!/usr/bin/tclsh

package require Tk

wm title . Dateisuche
wm geometry . -0+0
destroy {*}[winfo children .]

pack [entry .searchString] -expand no -fill x
pack [text .searchResult -height 5 -wrap none] -expand yes -fill both
pack [entry .run] -expand no -fill x

proc cursorWatch {} {
  foreach win [concat . [winfo children .]] {
    dict set pointer $win [$win cget -cursor]
    $win configure -cursor watch
  }
  update
  dict for {win cursor} $pointer {
    $win configure -cursor $cursor
  }
}

proc searchFiles {{str *}} {
  if {[string is lower $str]} then {
    set pat ""
    foreach let [split $str ""] {
      if {[string is alpha $let]} then {
        append pat \[ [string toupper $let] [string tolower $let] \]
      } else {
        append pat $let
      }
    }
  } else {
    set pat $str
  }
  append pat *
  exec find [file normalize ~] -name $pat
  # exec plocate -i $pat
}

bind .searchString <Key-Return> {
  cursorWatch
  catch {
    .searchResult replace 1.0 end [searchFiles [.searchString get]]
  }
}

bind .searchResult <Double-Button-1> {
  %W tag remove sel 1.0 end
  %W tag add sel "insert linestart" "insert lineend"
  break
}

event add <<Invoke>> <Triple-Button-1> <Control-Button-1>

foreach command {nemo thunar} {
  catch {
    # falls das Kommando $command existiert,
    # kannst du aufhören!
    if {[exec which $command] ne ""} break
  }
}

bind .searchResult <<Invoke>> {
  cursorWatch
  %W tag remove sel 1.0 end
  %W mark set insert @%x,%y
  %W tag add sel "insert linestart" "insert lineend"
  exec $command [%W get "insert linestart" "insert lineend"] &
  break
}

bind .run <Key-Return> {
  exec {*}[.run get] &
}

bind .run <<Paste>> {
  if {[catch {clipboard get}]} break
  %W delete 0 end
  %W insert 0 [list $command [string trim [clipboard get]]]
  break
}

menu .context -tearoff no
.context add command -label Copy -command {
  event generate [focus] <<Copy>>
}

.context add command -label Paste -command {
  event generate [focus] <<Paste>>
}

bind .searchResult <Button-3><ButtonRelease> {
  focus %W
  tk_popup .context %X %Y 0
}
bind .run <Button-3><ButtonRelease> {
  focus %W
  tk_popup .context %X %Y 1
}

15.10.2022