"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/npm/lib/help-search.js" (11 Apr 2017, 5786 Bytes) of package /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 
    2 module.exports = helpSearch
    3 
    4 var fs = require('graceful-fs')
    5 var path = require('path')
    6 var asyncMap = require('slide').asyncMap
    7 var npm = require('./npm.js')
    8 var glob = require('glob')
    9 var color = require('ansicolors')
   10 var output = require('./utils/output.js')
   11 
   12 helpSearch.usage = 'npm help-search <text>'
   13 
   14 function helpSearch (args, silent, cb) {
   15   if (typeof cb !== 'function') {
   16     cb = silent
   17     silent = false
   18   }
   19   if (!args.length) return cb(helpSearch.usage)
   20 
   21   var docPath = path.resolve(__dirname, '..', 'doc')
   22   return glob(docPath + '/*/*.md', function (er, files) {
   23     if (er) return cb(er)
   24     readFiles(files, function (er, data) {
   25       if (er) return cb(er)
   26       searchFiles(args, data, function (er, results) {
   27         if (er) return cb(er)
   28         formatResults(args, results, cb)
   29       })
   30     })
   31   })
   32 }
   33 
   34 function readFiles (files, cb) {
   35   var res = {}
   36   asyncMap(files, function (file, cb) {
   37     fs.readFile(file, 'utf8', function (er, data) {
   38       res[file] = data
   39       return cb(er)
   40     })
   41   }, function (er) {
   42     return cb(er, res)
   43   })
   44 }
   45 
   46 function searchFiles (args, files, cb) {
   47   var results = []
   48   Object.keys(files).forEach(function (file) {
   49     var data = files[file]
   50 
   51     // skip if no matches at all
   52     var match
   53     for (var a = 0, l = args.length; a < l && !match; a++) {
   54       match = data.toLowerCase().indexOf(args[a].toLowerCase()) !== -1
   55     }
   56     if (!match) return
   57 
   58     var lines = data.split(/\n+/)
   59 
   60     // if a line has a search term, then skip it and the next line.
   61     // if the next line has a search term, then skip all 3
   62     // otherwise, set the line to null.  then remove the nulls.
   63     l = lines.length
   64     for (var i = 0; i < l; i++) {
   65       var line = lines[i]
   66       var nextLine = lines[i + 1]
   67       var ll
   68 
   69       match = false
   70       if (nextLine) {
   71         for (a = 0, ll = args.length; a < ll && !match; a++) {
   72           match = nextLine.toLowerCase()
   73                   .indexOf(args[a].toLowerCase()) !== -1
   74         }
   75         if (match) {
   76           // skip over the next line, and the line after it.
   77           i += 2
   78           continue
   79         }
   80       }
   81 
   82       match = false
   83       for (a = 0, ll = args.length; a < ll && !match; a++) {
   84         match = line.toLowerCase().indexOf(args[a].toLowerCase()) !== -1
   85       }
   86       if (match) {
   87         // skip over the next line
   88         i++
   89         continue
   90       }
   91 
   92       lines[i] = null
   93     }
   94 
   95     // now squish any string of nulls into a single null
   96     lines = lines.reduce(function (l, r) {
   97       if (!(r === null && l[l.length - 1] === null)) l.push(r)
   98       return l
   99     }, [])
  100 
  101     if (lines[lines.length - 1] === null) lines.pop()
  102     if (lines[0] === null) lines.shift()
  103 
  104     // now see how many args were found at all.
  105     var found = {}
  106     var totalHits = 0
  107     lines.forEach(function (line) {
  108       args.forEach(function (arg) {
  109         var hit = (line || '').toLowerCase()
  110                   .split(arg.toLowerCase()).length - 1
  111         if (hit > 0) {
  112           found[arg] = (found[arg] || 0) + hit
  113           totalHits += hit
  114         }
  115       })
  116     })
  117 
  118     var cmd = 'npm help '
  119     if (path.basename(path.dirname(file)) === 'api') {
  120       cmd = 'npm apihelp '
  121     }
  122     cmd += path.basename(file, '.md').replace(/^npm-/, '')
  123     results.push({
  124       file: file,
  125       cmd: cmd,
  126       lines: lines,
  127       found: Object.keys(found),
  128       hits: found,
  129       totalHits: totalHits
  130     })
  131   })
  132 
  133   // if only one result, then just show that help section.
  134   if (results.length === 1) {
  135     return npm.commands.help([results[0].file.replace(/\.md$/, '')], cb)
  136   }
  137 
  138   if (results.length === 0) {
  139     output('No results for ' + args.map(JSON.stringify).join(' '))
  140     return cb()
  141   }
  142 
  143   // sort results by number of results found, then by number of hits
  144   // then by number of matching lines
  145   results = results.sort(function (a, b) {
  146     return a.found.length > b.found.length ? -1
  147          : a.found.length < b.found.length ? 1
  148          : a.totalHits > b.totalHits ? -1
  149          : a.totalHits < b.totalHits ? 1
  150          : a.lines.length > b.lines.length ? -1
  151          : a.lines.length < b.lines.length ? 1
  152          : 0
  153   })
  154 
  155   cb(null, results)
  156 }
  157 
  158 function formatResults (args, results, cb) {
  159   if (!results) return cb(null)
  160 
  161   var cols = Math.min(process.stdout.columns || Infinity, 80) + 1
  162 
  163   var out = results.map(function (res) {
  164     var out = res.cmd
  165     var r = Object.keys(res.hits)
  166       .map(function (k) {
  167         return k + ':' + res.hits[k]
  168       }).sort(function (a, b) {
  169         return a > b ? 1 : -1
  170       }).join(' ')
  171 
  172     out += ((new Array(Math.max(1, cols - out.length - r.length)))
  173              .join(' ')) + r
  174 
  175     if (!npm.config.get('long')) return out
  176 
  177     out = '\n\n' + out + '\n' +
  178       (new Array(cols)).join('—') + '\n' +
  179       res.lines.map(function (line, i) {
  180         if (line === null || i > 3) return ''
  181         for (var out = line, a = 0, l = args.length; a < l; a++) {
  182           var finder = out.toLowerCase().split(args[a].toLowerCase())
  183           var newOut = ''
  184           var p = 0
  185 
  186           finder.forEach(function (f) {
  187             newOut += out.substr(p, f.length)
  188 
  189             var hilit = out.substr(p + f.length, args[a].length)
  190             if (npm.color) hilit = color.bgBlack(color.red(hilit))
  191             newOut += hilit
  192 
  193             p += f.length + args[a].length
  194           })
  195         }
  196 
  197         return newOut
  198       }).join('\n').trim()
  199     return out
  200   }).join('\n')
  201 
  202   if (results.length && !npm.config.get('long')) {
  203     out = 'Top hits for ' + (args.map(JSON.stringify).join(' ')) + '\n' +
  204           (new Array(cols)).join('—') + '\n' +
  205           out + '\n' +
  206           (new Array(cols)).join('—') + '\n' +
  207           '(run with -l or --long to see more context)'
  208   }
  209 
  210   output(out.trim())
  211   cb(null, results)
  212 }