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