diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..722d5e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode diff --git a/highlight_duplicates.sublime-settings b/highlight_duplicates.sublime-settings index 91d755f..2ae0654 100644 --- a/highlight_duplicates.sublime-settings +++ b/highlight_duplicates.sublime-settings @@ -8,7 +8,15 @@ // If true, whitespace gets trimmed off each line before checking for matching lines "trim_white_space" : true, + // If true, letter casing is ignored for checking for matching lines "ignore_case" : false, - "min_line_length" : 4 + // The minimun length a line needs to be in order to be included as a matching line + "min_line_length" : 4, + + // The minimum number of duplicate lines needed to be found, in order to be included as a matching line + "min_duplicate_count" : 1, + + // Lines that match entries in this list are ignored as matching lines + "ignore_list" : [] } diff --git a/hightlight_duplicates.py b/hightlight_duplicates.py index 9997c49..d46dc89 100644 --- a/hightlight_duplicates.py +++ b/hightlight_duplicates.py @@ -25,8 +25,9 @@ DEFAULT_IS_ENABLED = True DEFAULT_IS_DISABLED = False DEFAULT_MIN_LINE_LENGTH = 4 +DEFAULT_MIN_DUPLICATE_COUNT = 1 -def count_lines(lines, view, minLineLength): +def count_lines(lines, view): '''Counts line occurrences of a view using a hash. The lines are stripped and tested before count. ''' @@ -37,18 +38,19 @@ def count_lines(lines, view, minLineLength): string = string.strip() if ignoreCase(): string = string.lower() - if is_candidate(string, minLineLength): + if is_candidate(string): counts[string].append(line) return counts -def filter_counts(counts, treshold=1): +def filter_counts(counts): '''Filters the line counts by rejecting every line having a count - lower or equal to the treshold, which defaults to 1. + lower or equal to the "min_duplicate_count" user setting, which defaults to 1. ''' filtered = dict() + threshold = getMinDuplicateCount(); for k, v in counts.items(): - if len(v) > treshold: + if len(v) > threshold: filtered[k] = v return filtered @@ -74,10 +76,14 @@ def merge_results(countsList): return merged -def is_candidate(string, minLineLength): +def is_candidate(string): '''Tells if a string is a LOC candidate. A candidate is a string long enough after stripping some symbols. ''' + minLineLength = getMinLineLength() + ignoreList = getIgnoreList() + if len(ignoreList) > 0 and string.strip().lower() in ignoreList: + return False return len(string.strip('{}()[]/')) >= minLineLength @@ -110,7 +116,7 @@ def highlight_duplicates(view): # get all lines lines = view.lines(sublime.Region(0, view.size())) # count and filter out non duplicated lines - duplicates = filter_counts(count_lines(lines, view, getMinLineLength())) + duplicates = filter_counts(count_lines(lines, view)) # show duplicated lines show_lines(duplicates.values(), view) @@ -121,7 +127,7 @@ def select_duplicates(view): # get all lines lines = view.lines(sublime.Region(0, view.size())) # count and filter out non duplicated lines - duplicates = filter_counts(count_lines(lines, view, getMinLineLength())) + duplicates = filter_counts(count_lines(lines, view)) # select duplicated lines add_lines(duplicates.values(), view) @@ -132,7 +138,7 @@ def remove_duplicates(view, edit): # get all lines lines = view.lines(sublime.Region(0, view.size())) # count and filter out non duplicated lines - duplicates = remove_first(filter_counts(count_lines(lines, view, getMinLineLength()))) + duplicates = remove_first(filter_counts(count_lines(lines, view))) # select duplicated lines merged = merge_results(duplicates.values()) merged.sort(key=lambda elm: elm.begin()) @@ -172,6 +178,22 @@ def getMinLineLength(): else: return DEFAULT_MIN_LINE_LENGTH +def getMinDuplicateCount(): + settings = sublime.load_settings('highlight_duplicates.sublime-settings') + minLength = settings.get('min_duplicate_count', DEFAULT_MIN_DUPLICATE_COUNT) + if isinstance(minLength, int): + return max(DEFAULT_MIN_DUPLICATE_COUNT, minLength) + else: + return DEFAULT_MIN_DUPLICATE_COUNT + +def getIgnoreList(): + settings = sublime.load_settings('highlight_duplicates.sublime-settings') + ignoreList = settings.get('ignore_list', []) + for i in range(len(ignoreList)): + ignoreList[i] = ignoreList[i].strip().lower() + + return ignoreList + class HighlightDuplicatesCommand(sublime_plugin.WindowCommand): diff --git a/messages/1.5.0.txt b/messages/1.5.0.txt new file mode 100644 index 0000000..5927872 --- /dev/null +++ b/messages/1.5.0.txt @@ -0,0 +1,15 @@ +Highlight Duplicates v1.5.0 + + • Added Min Duplicate Count Setting + + The number of matching lines, beyond the first, that need to be found in order to be counted as duplicates. + + Default: + "min_duplicate_count": 1 + + • Added Ignore List Setting + + Lines matching entries in this list, will be ignored for all functions. Leading and trailing white space, as well as letter case, will be ignored when checking lines against the ignore list. + + Default: + "ignore_list": [] diff --git a/readme.md b/readme.md index 410ec16..9477bca 100644 --- a/readme.md +++ b/readme.md @@ -8,7 +8,7 @@ This is a [Sublime Text 3](http://www.sublimetext.com/3) (and ST2) plugin. **Using Package Control** ([installation instructions](https://packagecontrol.io/installation)) -Press ctrl+shift+p (cmd+shift+p for OSX), then use the 'Package Control: Install Package' command. +Press ctrl+shift+p (cmd+shift+p for OSX), then use the 'Package Control: Install Package' command. Search for 'HighlightDuplicates', and press enter to install. @@ -31,7 +31,7 @@ That's it! ## Commands -### Toggle Highlighting +### Toggle Highlighting Using this command will turn the plugin on and off. This allows you to see the highlighted only when you want without having to disable/enable to plugin via the Package Control. @@ -50,17 +50,17 @@ For example... 1: 2: Content 3: -4: -``` +4: +``` Would result in ``` html 1: 2: Content -3: +3: ``` -_Note:_ By default none of these commands have a key binding, and can only be used via the Command Palette. You can set a key binding by adding any of the following lines to the key binding file. (Preferences > Key Bindings) +_Note:_ By default none of these commands have a key binding, and can only be used via the Command Palette. You can set a key binding by adding any of the following lines to the key binding file. (Preferences > Key Bindings) ``` js { "keys": ["alt+shift+h"], "command": "toggle_highlight_duplicates" } @@ -70,8 +70,8 @@ _Note:_ By default none of these commands have a key binding, and can only be us ## Options -### Change The Highlighting Color -`Default: "invalid"` +### Change The Highlighting Color +`highlight_duplicates_color: "invalid"` The highlighting color can be changed by providing a scope name such as "invalid", "comment", etc... @@ -80,41 +80,41 @@ If you'd like to use a custom color, it should be defined as a color scope in your theme file. -### Trim White Space -`Default: true` +### Trim White Space +`trim_white_space: true` If this setting is true, the leading and trailing white space will be removed before being compared to other lines. This setting also affects which lines are selected when using the 'Select Duplicates' command. -For example, if `"trim_white_space" : true` the following 2 lines will be counted as duplicates. +For example, if `"trim_white_space" : true` the following 2 lines will be counted as duplicates. ``` html 1: 2: -``` -However, the following lines would not be counted as duplicates. The reason for this is because there is white space in line 1 that is not leading or trailing, which does not appear in line 2. +``` +However, the following lines would not be counted as duplicates. The reason for this is because there is white space in line 1 that is not leading or trailing, which does not appear in line 2. ``` html 1: 2: ``` -### Ignore Case -`Default: false` +### Ignore Case +`ignore_case: false` If this setting is true, upper and lower case letters will be considered the same. This setting also affects which lines are selected when using the 'Select Duplicates' command. -For example, if `"ignore_case" : true` the following 2 lines will be counted as duplicates. +For example, if `"ignore_case" : true` the following 2 lines will be counted as duplicates. ``` html 1: 2: ``` -### Min Line Length -`Default: 4` +### Min Line Length +`min_line_length: 4` Lines with fewer characters than specified in this setting, will be ignored for all functions. Setting this to 1 will cause all non empty lines to be possible duplicates. -For example, by default, only lines 7 and 8 will be selected when using the "select duplicate" command. If this setting is set to 2, all the lines except lines 1 and 2 will be selected when using the "select duplicate" command. +For example, by default, only lines 7 and 8 will be selected when using the "select duplicate" command. If this setting is set to 2, all the lines except lines 1 and 2 will be selected when using the "select duplicate" command. ``` html 1: 1 2: 1 @@ -125,3 +125,37 @@ For example, by default, only lines 7 and 8 will be selected when using the "sel 7: 1234 8: 1234 ``` + + + +### Min Duplicate Count +`min_duplicate_count: 1` + +The number of matching lines, beyond the first, that need to be found in order to be counted as duplicates. + +For example, setting this option to `2`, will make it so only lines 3-5 are highlighted below. + +``` html +1: not this +2: not this +3: this +4: this +5: this +``` + + + +### Ignore List +`ignore_list: []` + +Lines matching entires in this list, will be ignored for all functions. Leading and trailing white space, as well as letter case, will be ignored when checking lines against the ignore list. + +` + "ignore_list": ["This line will be ignored"] +` +``` html +1: This line will be ignored +2: This line will be ignored +3: This line will not be ignored +4: This line will not be ignored +```