1
0

ruby_file_scanner.rb 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. # Copyright 2010-2014 Wincent Colaiuta. All rights reserved.
  2. #
  3. # Redistribution and use in source and binary forms, with or without
  4. # modification, are permitted provided that the following conditions are met:
  5. #
  6. # 1. Redistributions of source code must retain the above copyright notice,
  7. # this list of conditions and the following disclaimer.
  8. # 2. Redistributions in binary form must reproduce the above copyright notice,
  9. # this list of conditions and the following disclaimer in the documentation
  10. # and/or other materials provided with the distribution.
  11. #
  12. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  13. # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  14. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  15. # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
  16. # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  17. # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  18. # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  19. # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  20. # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  21. # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  22. # POSSIBILITY OF SUCH DAMAGE.
  23. require 'command-t/vim'
  24. require 'command-t/scanner/file_scanner'
  25. module CommandT
  26. class FileScanner
  27. # Pure Ruby implementation of a file scanner.
  28. class RubyFileScanner < FileScanner
  29. def paths
  30. super || begin
  31. @paths[@path] = []
  32. @depth = 0
  33. @files = 0
  34. set_wild_ignore(@wild_ignore)
  35. add_paths_for_directory @path, @paths[@path]
  36. rescue FileLimitExceeded
  37. ensure
  38. set_wild_ignore(@base_wild_ignore)
  39. end
  40. @paths[@path]
  41. end
  42. private
  43. def looped_symlink? path
  44. if File.symlink?(path)
  45. target = File.expand_path(File.readlink(path), File.dirname(path))
  46. target.include?(@path) || @path.include?(target)
  47. end
  48. end
  49. def add_paths_for_directory dir, accumulator
  50. Dir.foreach(dir) do |entry|
  51. next if ['.', '..'].include?(entry)
  52. path = File.join(dir, entry)
  53. unless path_excluded?(path)
  54. if File.file?(path)
  55. @files += 1
  56. raise FileLimitExceeded if @files > @max_files
  57. accumulator << path[@prefix_len + 1..-1]
  58. elsif File.directory?(path)
  59. next if @depth >= @max_depth
  60. next if (entry.match(/\A\./) && !@scan_dot_directories)
  61. next if looped_symlink?(path)
  62. @depth += 1
  63. add_paths_for_directory path, accumulator
  64. @depth -= 1
  65. end
  66. end
  67. end
  68. rescue Errno::EACCES
  69. # skip over directories for which we don't have access
  70. end
  71. end # class RubyFileScanner
  72. end # class FileScanner
  73. end # module CommandT