starscope 1.5.7 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 16cc0b7d5c3226ca3680b475dfcd923348352d9f
4
- data.tar.gz: f3c98060b7b84c54fc13fab3469387f691dfb76f
2
+ SHA256:
3
+ metadata.gz: d71f7d9d5748e9df63987f08669e56866a5669a7877a5b78bec7274ae6b11e3b
4
+ data.tar.gz: a037cc0b16644f69a37c1d9a00f076a036353cb84cbcaef39e17f864af2c70eb
5
5
  SHA512:
6
- metadata.gz: 6b56db7031396663009a1d062b7444ada17e3d103f2bb972e6bd94b6211eb22a4a44d3891ae1e9a01dc8317800d64438c3f45d4fa25fc8dd17e8e8e1f9ce36bc
7
- data.tar.gz: 7080292f2aaa289b20733edf0a40594ad213864cdda3b7c014143aae6405c51aa142993b52058313f8ddfa0703401db21c47eec0b7d30cfcc36de94648c344b4
6
+ metadata.gz: 85d4390356102ec0dfc658fa99bb8816a197f48f990abe56fd5b1df7ac85d3d1ffdd93666ca463ca9c42a362ae81a369cc81fa700c83729a9e73a9ba1e431730
7
+ data.tar.gz: 6cb4cc84d760ba1e5114f2401878e9312eff5e1b7d30ae7b3c4feec10a76c0f87f1f3d00de59417aee8e5e57aa2eb9744ae6a851303b964d9b8edaf8fcec3dad
@@ -0,0 +1,26 @@
1
+ name: Ruby CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby-version: ['2.6', '2.7', '3.0', '3.1']
15
+
16
+ steps:
17
+ - uses: actions/checkout@v2
18
+ - name: Set up Ruby
19
+ uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby-version }}
22
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
23
+ - name: Run tests
24
+ run: bundle exec rake test
25
+ - name: Lint
26
+ run: bundle exec rubocop
data/.rubocop.yml CHANGED
@@ -1,6 +1,15 @@
1
+ require:
2
+ - rubocop-minitest
3
+ - rubocop-rake
4
+
1
5
  AllCops:
6
+ NewCops: enable
2
7
  Exclude:
3
- - 'test/fixtures/sample_ruby.rb'
8
+ - test/fixtures/sample_ruby.rb
9
+ - vendor/bundle/**/*
10
+
11
+ Layout/LineLength:
12
+ Max: 120
4
13
 
5
14
  Metrics/AbcSize:
6
15
  Enabled: false
@@ -17,9 +26,6 @@ Metrics/ClassLength:
17
26
  Metrics/CyclomaticComplexity:
18
27
  Enabled: false
19
28
 
20
- Metrics/LineLength:
21
- Max: 120
22
-
23
29
  Metrics/MethodLength:
24
30
  Enabled: false
25
31
 
data/CHANGELOG.md CHANGED
@@ -1,6 +1,24 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ v1.6.0 (2022-02-10)
5
+ -------------------
6
+
7
+ Improvements:
8
+ * Support per-directory `.starscope.json` config (#181).
9
+ * Support abbreviated special commands in line mode (e.g. `!u`, `!s`, `!q`).
10
+ * Properly support non-ASCII identifiers in Golang.
11
+ * Tiny performance improvements.
12
+
13
+ Bug Fixes:
14
+ * Strip non-ASCII characters from cscope export to avoid cscope crashes (#182).
15
+
16
+ Misc:
17
+ * Drop support for ancient Marshall-format databases.
18
+ * Drop support for several old Ruby versions. 2.6 is now the oldest supported.
19
+ * Dependency upgrades.
20
+ * Documentation improvements.
21
+
4
22
  v1.5.7 (2019-04-04)
5
23
  --------------------
6
24
 
data/README.md CHANGED
@@ -2,7 +2,7 @@ Starscope
2
2
  =========
3
3
 
4
4
  [![Gem Version](https://img.shields.io/gem/v/starscope.svg)](https://rubygems.org/gems/starscope)
5
- [![Build Status](https://travis-ci.org/eapache/starscope.svg?branch=master)](https://travis-ci.org/eapache/starscope)
5
+ [![Ruby CI](https://github.com/eapache/starscope/actions/workflows/ruby-ci.yml/badge.svg)](https://github.com/eapache/starscope/actions/workflows/ruby-ci.yml)
6
6
  [![Code of Conduct](https://img.shields.io/badge/code%20of%20conduct-active-blue.svg)](https://eapache.github.io/conduct.html)
7
7
 
8
8
  Starscope is a code indexer, search and navigation tool for
data/Rakefile CHANGED
@@ -6,7 +6,10 @@ Rake::TestTask.new do |t|
6
6
  t.test_files = FileList['test/**/*_test.rb']
7
7
  end
8
8
 
9
- RuboCop::RakeTask.new
9
+ RuboCop::RakeTask.new do |t|
10
+ t.requires << 'rubocop-minitest'
11
+ t.requires << 'rubocop-rake'
12
+ end
10
13
 
11
14
  desc 'Run tests and style checks'
12
- task default: [:test, :rubocop]
15
+ task default: %i[test rubocop]
data/bin/starscope CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- lib = File.expand_path('../../lib', __FILE__)
3
+ lib = File.expand_path('../lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  require 'oj'
@@ -9,7 +9,7 @@ require 'readline'
9
9
  require 'starscope'
10
10
 
11
11
  DEFAULT_DB = '.starscope.db'.freeze
12
- CONFIG_FILE = File.join(Dir.home, '.starscope.json')
12
+ CONFIG_FILE = File.exist?('.starscope.json') ? '.starscope.json' : File.join(Dir.home, '.starscope.json')
13
13
  GLOBAL_CONFIG = File.exist?(CONFIG_FILE) ? Oj.load_file(CONFIG_FILE, symbol_keys: true) : {}
14
14
 
15
15
  options = { read: true,
@@ -21,20 +21,20 @@ options = { read: true,
21
21
 
22
22
  # Options Parsing
23
23
  OptionParser.new do |opts|
24
- opts.banner = <<END
25
- Usage: starscope [options] [PATHS]
24
+ opts.banner = <<~BANNER
25
+ Usage: starscope [options] [PATHS]
26
26
 
27
- The default database is `#{DEFAULT_DB}` if you don't specify one with -f.
28
- The default behaviour is to read and update the database.
29
- If no database exists and no PATHS are specified, Starscope builds a new
30
- database by recursing in the current directory.
27
+ The default database is `#{DEFAULT_DB}` if you don't specify one with -f.
28
+ The default behaviour is to read and update the database.
29
+ If no database exists and no PATHS are specified, Starscope builds a new
30
+ database by recursing in the current directory.
31
31
 
32
- Scoped queries must use `::` as the scope separator, even for languages which
33
- have their own scope syntax.
32
+ Scoped queries must use `::` as the scope separator, even for languages which
33
+ have their own scope syntax.
34
34
 
35
- Website: https://github.com/eapache/starscope
36
- User Manual: https://github.com/eapache/starscope/blob/master/doc/USER_GUIDE.md
37
- END
35
+ Website: https://github.com/eapache/starscope
36
+ User Manual: https://github.com/eapache/starscope/blob/master/doc/USER_GUIDE.md
37
+ BANNER
38
38
 
39
39
  opts.separator "\nQueries"
40
40
  opts.on('-d', '--dump [TABLE]', 'Dumps the DB or specified table to stdout') do |tbl|
@@ -81,32 +81,32 @@ END
81
81
  end
82
82
  opts.on('--verbose', 'Print extra status messages') do
83
83
  if options[:output] == :quiet
84
- $stderr.puts "Can't be both verbose and quiet"
84
+ warn "Can't be both verbose and quiet"
85
85
  exit(1)
86
86
  end
87
87
  options[:output] = :verbose
88
88
  end
89
89
  opts.on('--quiet', 'Print fewer messages') do
90
90
  if options[:output] == :verbose
91
- $stderr.puts "Can't be both verbose and quiet"
91
+ warn "Can't be both verbose and quiet"
92
92
  exit(1)
93
93
  end
94
94
  options[:output] = :quiet
95
95
  end
96
96
 
97
- opts.separator <<END
98
- \nEXPORTING
99
- At the moment two export formats are supported: 'ctags' and 'cscope'. If
100
- you don't specify a path, the output is written to the file '#{Starscope::Exportable::CTAGS_DEFAULT_PATH}' (for
101
- ctags) or '#{Starscope::Exportable::CSCOPE_DEFAULT_PATH}' (for cscope) in the current directory.
102
- END
97
+ opts.separator <<~TAIL
98
+ \nEXPORTING
99
+ At the moment two export formats are supported: 'ctags' and 'cscope'. If
100
+ you don't specify a path, the output is written to the file '#{Starscope::Exportable::CTAGS_DEFAULT_PATH}' (for
101
+ ctags) or '#{Starscope::Exportable::CSCOPE_DEFAULT_PATH}' (for cscope) in the current directory.
102
+ TAIL
103
103
  end.parse!
104
104
 
105
105
  def print_summary(db)
106
106
  tables = db.tables
107
107
  puts 'No tables' if tables.empty?
108
108
  tables.sort.each do |table|
109
- printf("%-9s %6d records\n", table, db.records(table).length)
109
+ printf("%<table>-9s %<length>6d records\n", table: table, length: db.records(table).length)
110
110
  end
111
111
  end
112
112
 
@@ -134,7 +134,7 @@ def run_query(db, query, separator)
134
134
  match = match.join(separator)
135
135
 
136
136
  if match.empty?
137
- $stderr.puts 'Invalid input - no query found.'
137
+ warn 'Invalid input - no query found.'
138
138
  return false
139
139
  end
140
140
  tables = (table == '*' ? db.tables : table.to_sym)
@@ -146,10 +146,10 @@ def run_query(db, query, separator)
146
146
  puts format_record(db, rec)
147
147
  end
148
148
  end
149
- return true
149
+ true
150
150
  rescue Starscope::DB::NoTableError
151
- $stderr.puts "Table '#{table}' doesn't exist."
152
- return false
151
+ warn "Table '#{table}' doesn't exist."
152
+ false
153
153
  end
154
154
 
155
155
  def dump_table(db, table)
@@ -174,22 +174,22 @@ def dump(db, table)
174
174
  when '_files'
175
175
  puts db.metadata(:files).keys
176
176
  when /^_/
177
- puts db.metadata(table[1..-1].to_sym)
177
+ puts db.metadata(table[1..].to_sym)
178
178
  else
179
179
  dump_table(db, table.to_sym)
180
180
  end
181
181
 
182
- return true
182
+ true
183
183
  rescue Starscope::DB::NoTableError
184
- $stderr.puts "Table '#{table}' doesn't exist."
185
- return false
184
+ warn "Table '#{table}' doesn't exist."
185
+ false
186
186
  end
187
187
 
188
188
  def export(db, param)
189
189
  format, path = param.split(',', 2)
190
190
  db.export(format.to_sym, path)
191
191
  rescue Starscope::Exportable::UnknownExportFormatError
192
- $stderr.puts "Unrecognized export format \"#{format}\""
192
+ warn "Unrecognized export format \"#{format}\""
193
193
  end
194
194
 
195
195
  output = Starscope::Output.new(options[:output])
@@ -246,18 +246,19 @@ if options[:dump]
246
246
  end
247
247
 
248
248
  def linemode_help
249
- <<END
250
- Input can be a query of the form 'TABLE QUERY' or a special command starting
251
- with a '!'. Recognized special commands are:
252
- !dump [TABLE]
253
- !export FORMAT[,PATH]
254
- !summary
255
- !update
256
-
257
- !help
258
- !version
259
- !quit
260
- END
249
+ <<~HELP
250
+ Input can be a query of the form 'TABLE QUERY' or a special command starting
251
+ with a '!'. Recognized special commands are:
252
+ !dump [TABLE]
253
+ !export FORMAT[,PATH]
254
+ !summary
255
+ !update
256
+
257
+ !help
258
+ !version
259
+ !quit
260
+ Abbreviations of special commands (e.g `!u` or `!q`) are also recognized.
261
+ HELP
261
262
  end
262
263
 
263
264
  if options[:linemode]
@@ -265,27 +266,28 @@ if options[:linemode]
265
266
  begin
266
267
  while (input = Readline.readline('> ', true))
267
268
  next if input.empty?
269
+
268
270
  cmd, param = input.split(' ', 2)
269
271
  if cmd[0] == '!'
270
- case cmd[1..-1]
271
- when 'dump'
272
+ case cmd[1..]
273
+ when 'dump', 'd'
272
274
  dump(db, param)
273
- when 'export'
275
+ when 'export', 'e', 'ex'
274
276
  if param
275
277
  export(db, param)
276
278
  else
277
279
  puts '!export requires an argument'
278
280
  end
279
- when 'summary'
281
+ when 'summary', 's', 'sum'
280
282
  print_summary(db)
281
- when 'update'
283
+ when 'update', 'u', 'up'
282
284
  changed = db.update
283
285
  db.save(options[:db]) if options[:write] && changed
284
- when 'help'
286
+ when 'help', 'h'
285
287
  puts linemode_help
286
- when 'version'
288
+ when 'version', 'v'
287
289
  puts Starscope::VERSION
288
- when 'quit'
290
+ when 'quit', 'q'
289
291
  exit
290
292
  else
291
293
  puts "Unknown command: '#{input}', try '!help'."
@@ -9,6 +9,14 @@ Already Supported
9
9
  * [JavaScript](https://en.wikipedia.org/wiki/JavaScript)
10
10
  (including ES6/ES7 and JSX via [Babel](https://babeljs.io/))
11
11
 
12
+ External Support
13
+ -----------------
14
+
15
+ Other languages are sometimes supported in third-party plugin files, or forks
16
+ which don't upstream their changes, but I try and list them here. I make no
17
+ warranty that these are still maintained or even work.
18
+ * [Puppet](https://github.com/fihuer/starscope/tree/language/puppet)
19
+
12
20
  How to Add Another Language
13
21
  ---------------------------
14
22
 
data/doc/USER_GUIDE.md CHANGED
@@ -109,14 +109,22 @@ Excluded patterns are also remembered, and can be added at any time. If an
109
109
  existing file in the database matches a newly added exclusion rule, it will be
110
110
  removed.
111
111
 
112
- For commonly excluded files you can create a `~/.starscope.json` file with
113
- contents like:
112
+ Paths to add and exclude are recursive by default. If you need more control, you
113
+ may use any special characters accepted by Ruby's
114
+ [`File::fnmatch`](https://ruby-doc.org/core-2.6.9/File.html#method-c-fnmatch).
115
+
116
+ You can automatically exclude files on a per-directory basis by creating a
117
+ `.starscope.json` file in a given directory with contents like:
114
118
  ```json
115
119
  {
116
- "excludes": ["foo", "bar"]
120
+ "excludes": ["foo", "bar/", "**/*.ext"]
117
121
  }
118
122
  ```
119
- Patterns listed there will be excluded from all starscope databases by default.
123
+
124
+ For commonly excluded files you can create a home directory config file at
125
+ `~/.starscope.json`. Patterns listed there will be excluded from all starscope
126
+ databases by default. Currently `excludes` is the only valid key for
127
+ `.starscope.json` files.
120
128
 
121
129
  Queries
122
130
  -------
@@ -177,6 +185,8 @@ non-line-mode options:
177
185
  * `!version` - same as the `--version` flag
178
186
  * `!quit` - exit line-mode
179
187
 
188
+ Abbreviations of special commands are also recognized (e.g. `!q` for `!quit`,
189
+ `!s` for `!summary`, etc).
180
190
 
181
191
  Miscellaneous
182
192
  -------------
data/lib/starscope/db.rb CHANGED
@@ -17,7 +17,7 @@ module Starscope
17
17
  FRAGMENT = :'!fragment'
18
18
 
19
19
  # dynamically load all our language extractors
20
- Dir.glob("#{File.dirname(__FILE__)}/langs/*.rb").each { |path| require path }
20
+ Dir.glob("#{File.dirname(__FILE__)}/langs/*.rb").sort.each { |path| require path }
21
21
 
22
22
  langs = {}
23
23
  extractors = []
@@ -31,6 +31,7 @@ module Starscope
31
31
 
32
32
  class NoTableError < StandardError; end
33
33
  class UnknownDBFormatError < StandardError; end
34
+ class TooOldDBFormatError < StandardError; end
34
35
 
35
36
  def initialize(output, config = {})
36
37
  @output = output
@@ -84,9 +85,9 @@ module Starscope
84
85
  paths = paths.map { |p| self.class.normalize_glob(p) }
85
86
  @meta[:paths] += paths
86
87
  @meta[:paths].uniq!
87
- files = Dir.glob(paths).select { |f| File.file? f }
88
- files.delete_if { |f| matches_exclude?(f) }
88
+ files = Dir.glob(paths).select { |f| File.file?(f) && !matches_exclude?(f) }
89
89
  return if files.empty?
90
+
90
91
  @output.new_pbar('Building', files.length)
91
92
  add_files(files)
92
93
  @output.finish_pbar
@@ -149,14 +150,12 @@ module Starscope
149
150
 
150
151
  def open_db(filename)
151
152
  File.open(filename, 'rb') do |file|
152
- begin
153
- Zlib::GzipReader.wrap(file) do |stream|
154
- parse_db(stream)
155
- end
156
- rescue Zlib::GzipFile::Error
157
- file.rewind
158
- parse_db(file)
153
+ Zlib::GzipReader.wrap(file) do |stream|
154
+ parse_db(stream)
159
155
  end
156
+ rescue Zlib::GzipFile::Error
157
+ file.rewind
158
+ parse_db(file)
160
159
  end
161
160
  end
162
161
 
@@ -166,28 +165,26 @@ module Starscope
166
165
  when DB_FORMAT
167
166
  @meta = Oj.load(stream.gets)
168
167
  @tables = Oj.load(stream.gets)
169
- return true
168
+ true
170
169
  when 3..4
171
170
  # Old format, so read the directories segment then rebuild
172
171
  add_paths(Oj.load(stream.gets))
173
- return false
172
+ false
174
173
  when 0..2
175
- # Old format (pre-json), so read the directories segment then rebuild
176
- len = stream.gets.to_i
177
- add_paths(Marshal.load(stream.read(len)))
178
- return false
174
+ raise TooOldDBFormatError
179
175
  else
180
176
  raise UnknownDBFormatError
181
177
  end
182
178
  rescue Oj::ParseError
183
179
  stream.rewind
184
180
  raise unless stream.gets.to_i == DB_FORMAT
181
+
185
182
  # try reading as formated json, which is much slower, but it is sometimes
186
183
  # useful to be able to directly read your db
187
184
  objects = []
188
185
  Oj.load(stream) { |obj| objects << obj }
189
186
  @meta, @tables = objects
190
- return true
187
+ true
191
188
  end
192
189
 
193
190
  def fixup
@@ -233,7 +230,7 @@ module Starscope
233
230
  self.class.extractors.each do |extractor|
234
231
  begin
235
232
  next unless extractor.match_file file
236
- rescue => e
233
+ rescue StandardError => e
237
234
  @output.normal("#{extractor} raised \"#{e}\" while matching #{file}")
238
235
  next
239
236
  end
@@ -271,8 +268,7 @@ module Starscope
271
268
  extract_file(Starscope::FragmentExtractor.new(lang, frags), file, line_cache, lines)
272
269
  @meta[:files][file][:sublangs] << lang
273
270
  end
274
-
275
- rescue => e
271
+ rescue StandardError => e
276
272
  @output.normal("#{extractor} raised \"#{e}\" while extracting #{file}")
277
273
  ensure
278
274
  # metadata must be created for any record that was inserted into a tbl
@@ -280,9 +276,7 @@ module Starscope
280
276
  @meta[:files][file][:lang] = extractor.name.split('::').last.to_sym
281
277
  @meta[:files][file][:lines] = lines
282
278
 
283
- if extractor_metadata.is_a? Hash
284
- @meta[:files][file] = extractor_metadata.merge!(@meta[:files][file])
285
- end
279
+ @meta[:files][file] = extractor_metadata.merge!(@meta[:files][file]) if extractor_metadata.is_a? Hash
286
280
  end
287
281
 
288
282
  def file_changed(name)
@@ -301,6 +295,7 @@ module Starscope
301
295
  def language_out_of_date(lang)
302
296
  return false unless lang
303
297
  return true unless LANGS[lang]
298
+
304
299
  (@meta[:langs][lang] || 0) < LANGS[lang]
305
300
  end
306
301
 
@@ -334,7 +329,8 @@ module Starscope
334
329
  args
335
330
  end
336
331
 
337
- def extractors # so we can stub it in tests
332
+ # so we can stub it in tests
333
+ def extractors
338
334
  EXTRACTORS
339
335
  end
340
336
  end
@@ -4,6 +4,7 @@ module Starscope
4
4
  module Exportable
5
5
  CTAGS_DEFAULT_PATH = 'tags'.freeze
6
6
  CSCOPE_DEFAULT_PATH = 'cscope.out'.freeze
7
+ ASCII = Encoding.find('ASCII')
7
8
 
8
9
  class UnknownExportFormatError < StandardError; end
9
10
 
@@ -39,14 +40,14 @@ module Starscope
39
40
  private
40
41
 
41
42
  def export_ctags(file, path_prefix)
42
- file.puts <<END
43
- !_TAG_FILE_FORMAT 2 /extended format/
44
- !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
45
- !_TAG_PROGRAM_AUTHOR Evan Huus /eapache@gmail.com/
46
- !_TAG_PROGRAM_NAME Starscope //
47
- !_TAG_PROGRAM_URL https://github.com/eapache/starscope //
48
- !_TAG_PROGRAM_VERSION #{Starscope::VERSION} //
49
- END
43
+ file.puts <<~HEADER
44
+ !_TAG_FILE_FORMAT 2 /extended format/
45
+ !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
46
+ !_TAG_PROGRAM_AUTHOR Evan Huus /eapache@gmail.com/
47
+ !_TAG_PROGRAM_NAME Starscope //
48
+ !_TAG_PROGRAM_URL https://github.com/eapache/starscope //
49
+ !_TAG_PROGRAM_VERSION #{Starscope::VERSION} //
50
+ HEADER
50
51
  defs = (@tables[:defs] || {}).sort_by { |x| x[:name][-1].to_s }
51
52
  defs.each do |record|
52
53
  file.puts ctag_line(record, @meta[:files][record[:file]], path_prefix)
@@ -150,7 +151,7 @@ END
150
151
  file.print("0\n")
151
152
  file.print("#{files.length}\n")
152
153
  buf = ''
153
- files.each { |f| buf << f + "\n" }
154
+ files.each { |f| buf << "#{f}\n" }
154
155
  file.print("#{buf.length}\n#{buf}")
155
156
  end
156
157
 
@@ -159,6 +160,7 @@ END
159
160
  @tables.each do |tbl, records|
160
161
  records.each do |record|
161
162
  next unless record[:line_no]
163
+
162
164
  record[:tbl] = tbl
163
165
  db[record[:file]] ||= {}
164
166
  db[record[:file]][record[:line_no]] ||= []
@@ -177,16 +179,14 @@ END
177
179
  # use the column if we have it, otherwise fall back to scanning
178
180
  index = record[:col] || line.index(key)
179
181
 
180
- while index && !valid_index?(line, index, key)
181
- index = line.index(key, index + 1)
182
- end
182
+ index = line.index(key, index + 1) while index && !valid_index?(line, index, key)
183
183
 
184
184
  next if index.nil?
185
185
 
186
186
  # Strip trailing non-word characters, otherwise cscope barfs on
187
187
  # function names like `include?`
188
188
  if key =~ /^\W*$/
189
- next unless [:defs, :end].include?(record[:tbl])
189
+ next unless %i[defs end].include?(record[:tbl])
190
190
  else
191
191
  key.sub!(/\W+$/, '')
192
192
  end
@@ -209,25 +209,23 @@ END
209
209
 
210
210
  index = line.index(key, prev)
211
211
 
212
- while index && index + key.length < offset && !valid_index?(line, index, key)
213
- index = line.index(key, index + 1)
214
- end
212
+ index = line.index(key, index + 1) while index && index + key.length < offset && !valid_index?(line, index, key)
215
213
 
216
214
  next unless index && index + key.length < offset
217
215
 
218
216
  buf << cscope_plaintext(line, prev, index) << "\n"
219
- buf << "#{key}\n"
217
+ buf << "#{strip_unicode(key)}\n"
220
218
  prev = index + key.length
221
219
  end
222
220
 
223
221
  buf << cscope_plaintext(line, prev, offset) << "\n"
224
- buf << cscope_mark(record) << record[:key] << "\n"
222
+ buf << cscope_mark(record) << strip_unicode(record[:key]) << "\n"
225
223
 
226
224
  buf << CSCOPE_GLOBAL_HACK_START if record[:type] == :func && record[:tbl] == :end
227
225
  buf
228
226
  rescue ArgumentError
229
227
  # invalid utf-8 byte sequence in the line, oh well
230
- line
228
+ strip_unicode(line)
231
229
  end
232
230
 
233
231
  def valid_index?(line, index, key)
@@ -242,10 +240,10 @@ END
242
240
  ret.lstrip! if start == 0
243
241
  ret.rstrip! if stop == line.length
244
242
  ret.gsub!(/\s+/, ' ')
245
- ret.empty? ? ' ' : ret
243
+ ret.empty? ? ' ' : strip_unicode(ret)
246
244
  rescue ArgumentError
247
245
  # invalid utf-8 byte sequence in the line, oh well
248
- line
246
+ strip_unicode(line)
249
247
  end
250
248
 
251
249
  def cscope_mark(rec)
@@ -260,16 +258,16 @@ END
260
258
  when :file
261
259
  ret = '@'
262
260
  when :defs
263
- case rec[:type]
264
- when :func
265
- ret = '$'
266
- when :class, :module
267
- ret = 'c'
268
- when :type
269
- ret = 't'
270
- else
271
- ret = 'g'
272
- end
261
+ ret = case rec[:type]
262
+ when :func
263
+ '$'
264
+ when :class, :module
265
+ 'c'
266
+ when :type
267
+ 't'
268
+ else
269
+ 'g'
270
+ end
273
271
  when :calls
274
272
  ret = '`'
275
273
  when :requires
@@ -282,7 +280,11 @@ END
282
280
  return ''
283
281
  end
284
282
 
285
- "\t" + ret
283
+ "\t#{ret}"
284
+ end
285
+
286
+ def strip_unicode(str)
287
+ str.encode(ASCII, invalid: :replace, undef: :replace, replace: '')
286
288
  end
287
289
  end
288
290
  end
@@ -5,16 +5,15 @@ module Starscope
5
5
  @frags = frags
6
6
  end
7
7
 
8
- def extract(path, text)
9
- text = @frags.map { |f| f.delete(:frag).strip }.join("\n")
8
+ def extract(path, _text)
9
+ compiled_text = @frags.map { |f| f.delete(:frag).strip }.join("\n")
10
10
 
11
- extractor_metadata = @child.extract(path, text) do |tbl, name, args|
11
+ @child.extract(path, compiled_text) do |tbl, name, args|
12
12
  args.merge!(@frags[args[:line_no] - 1]) if args[:line_no]
13
13
  yield tbl, name, args
14
14
  end
15
15
 
16
16
  # TODO: translate metadata?
17
- extractor_metadata
18
17
  end
19
18
 
20
19
  def name