thefuck-leeguoo 3.41__py2.py3-none-any.whl

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.
Files changed (218) hide show
  1. thefuck/__init__.py +0 -0
  2. thefuck/ai.py +765 -0
  3. thefuck/argument_parser.py +96 -0
  4. thefuck/conf.py +141 -0
  5. thefuck/const.py +111 -0
  6. thefuck/corrector.py +92 -0
  7. thefuck/entrypoints/__init__.py +0 -0
  8. thefuck/entrypoints/alias.py +28 -0
  9. thefuck/entrypoints/fix_command.py +105 -0
  10. thefuck/entrypoints/main.py +50 -0
  11. thefuck/entrypoints/not_configured.py +201 -0
  12. thefuck/entrypoints/setup.py +227 -0
  13. thefuck/entrypoints/shell_logger.py +79 -0
  14. thefuck/exceptions.py +10 -0
  15. thefuck/logs.py +255 -0
  16. thefuck/output_readers/__init__.py +20 -0
  17. thefuck/output_readers/read_log.py +108 -0
  18. thefuck/output_readers/rerun.py +72 -0
  19. thefuck/output_readers/shell_logger.py +60 -0
  20. thefuck/rules/__init__.py +0 -0
  21. thefuck/rules/adb_unknown_command.py +54 -0
  22. thefuck/rules/ag_literal.py +10 -0
  23. thefuck/rules/apt_get.py +50 -0
  24. thefuck/rules/apt_get_search.py +14 -0
  25. thefuck/rules/apt_invalid_operation.py +63 -0
  26. thefuck/rules/apt_list_upgradable.py +16 -0
  27. thefuck/rules/apt_upgrade.py +16 -0
  28. thefuck/rules/aws_cli.py +17 -0
  29. thefuck/rules/az_cli.py +17 -0
  30. thefuck/rules/brew_cask_dependency.py +33 -0
  31. thefuck/rules/brew_install.py +24 -0
  32. thefuck/rules/brew_link.py +15 -0
  33. thefuck/rules/brew_reinstall.py +19 -0
  34. thefuck/rules/brew_uninstall.py +14 -0
  35. thefuck/rules/brew_unknown_command.py +82 -0
  36. thefuck/rules/brew_update_formula.py +12 -0
  37. thefuck/rules/cargo.py +6 -0
  38. thefuck/rules/cargo_no_command.py +15 -0
  39. thefuck/rules/cat_dir.py +14 -0
  40. thefuck/rules/cd_correction.py +61 -0
  41. thefuck/rules/cd_cs.py +21 -0
  42. thefuck/rules/cd_mkdir.py +21 -0
  43. thefuck/rules/cd_parent.py +16 -0
  44. thefuck/rules/chmod_x.py +15 -0
  45. thefuck/rules/choco_install.py +25 -0
  46. thefuck/rules/composer_not_command.py +22 -0
  47. thefuck/rules/conda_mistype.py +17 -0
  48. thefuck/rules/cp_create_destination.py +15 -0
  49. thefuck/rules/cp_omitting_directory.py +15 -0
  50. thefuck/rules/cpp11.py +12 -0
  51. thefuck/rules/dirty_untar.py +53 -0
  52. thefuck/rules/dirty_unzip.py +60 -0
  53. thefuck/rules/django_south_ghost.py +8 -0
  54. thefuck/rules/django_south_merge.py +8 -0
  55. thefuck/rules/dnf_no_such_command.py +37 -0
  56. thefuck/rules/docker_image_being_used_by_container.py +20 -0
  57. thefuck/rules/docker_login.py +13 -0
  58. thefuck/rules/docker_not_command.py +49 -0
  59. thefuck/rules/dry.py +15 -0
  60. thefuck/rules/fab_command_not_found.py +38 -0
  61. thefuck/rules/fix_alt_space.py +15 -0
  62. thefuck/rules/fix_file.py +80 -0
  63. thefuck/rules/gem_unknown_command.py +36 -0
  64. thefuck/rules/git_add.py +27 -0
  65. thefuck/rules/git_add_force.py +13 -0
  66. thefuck/rules/git_bisect_usage.py +16 -0
  67. thefuck/rules/git_branch_0flag.py +24 -0
  68. thefuck/rules/git_branch_delete.py +13 -0
  69. thefuck/rules/git_branch_delete_checked_out.py +19 -0
  70. thefuck/rules/git_branch_exists.py +25 -0
  71. thefuck/rules/git_branch_list.py +14 -0
  72. thefuck/rules/git_checkout.py +49 -0
  73. thefuck/rules/git_clone_git_clone.py +12 -0
  74. thefuck/rules/git_clone_missing.py +42 -0
  75. thefuck/rules/git_commit_add.py +17 -0
  76. thefuck/rules/git_commit_amend.py +11 -0
  77. thefuck/rules/git_commit_reset.py +11 -0
  78. thefuck/rules/git_diff_no_index.py +16 -0
  79. thefuck/rules/git_diff_staged.py +13 -0
  80. thefuck/rules/git_fix_stash.py +37 -0
  81. thefuck/rules/git_flag_after_filename.py +31 -0
  82. thefuck/rules/git_help_aliased.py +12 -0
  83. thefuck/rules/git_hook_bypass.py +27 -0
  84. thefuck/rules/git_lfs_mistype.py +18 -0
  85. thefuck/rules/git_main_master.py +16 -0
  86. thefuck/rules/git_merge.py +18 -0
  87. thefuck/rules/git_merge_unrelated.py +12 -0
  88. thefuck/rules/git_not_command.py +18 -0
  89. thefuck/rules/git_pull.py +16 -0
  90. thefuck/rules/git_pull_clone.py +13 -0
  91. thefuck/rules/git_pull_uncommitted_changes.py +14 -0
  92. thefuck/rules/git_push.py +44 -0
  93. thefuck/rules/git_push_different_branch_names.py +12 -0
  94. thefuck/rules/git_push_force.py +18 -0
  95. thefuck/rules/git_push_pull.py +20 -0
  96. thefuck/rules/git_push_without_commits.py +12 -0
  97. thefuck/rules/git_rebase_merge_dir.py +17 -0
  98. thefuck/rules/git_rebase_no_changes.py +13 -0
  99. thefuck/rules/git_remote_delete.py +13 -0
  100. thefuck/rules/git_remote_seturl_add.py +12 -0
  101. thefuck/rules/git_rm_local_modifications.py +19 -0
  102. thefuck/rules/git_rm_recursive.py +16 -0
  103. thefuck/rules/git_rm_staged.py +19 -0
  104. thefuck/rules/git_stash.py +15 -0
  105. thefuck/rules/git_stash_pop.py +18 -0
  106. thefuck/rules/git_tag_force.py +13 -0
  107. thefuck/rules/git_two_dashes.py +14 -0
  108. thefuck/rules/go_run.py +16 -0
  109. thefuck/rules/go_unknown_command.py +28 -0
  110. thefuck/rules/gradle_no_task.py +34 -0
  111. thefuck/rules/gradle_wrapper.py +13 -0
  112. thefuck/rules/grep_arguments_order.py +23 -0
  113. thefuck/rules/grep_recursive.py +10 -0
  114. thefuck/rules/grunt_task_not_found.py +37 -0
  115. thefuck/rules/gulp_not_task.py +22 -0
  116. thefuck/rules/has_exists_script.py +13 -0
  117. thefuck/rules/heroku_multiple_apps.py +12 -0
  118. thefuck/rules/heroku_not_command.py +11 -0
  119. thefuck/rules/history.py +15 -0
  120. thefuck/rules/hostscli.py +27 -0
  121. thefuck/rules/ifconfig_device_not_found.py +23 -0
  122. thefuck/rules/java.py +17 -0
  123. thefuck/rules/javac.py +18 -0
  124. thefuck/rules/lein_not_task.py +19 -0
  125. thefuck/rules/ln_no_hard_link.py +23 -0
  126. thefuck/rules/ln_s_order.py +26 -0
  127. thefuck/rules/long_form_help.py +27 -0
  128. thefuck/rules/ls_all.py +10 -0
  129. thefuck/rules/ls_lah.py +12 -0
  130. thefuck/rules/man.py +33 -0
  131. thefuck/rules/man_no_space.py +10 -0
  132. thefuck/rules/mercurial.py +27 -0
  133. thefuck/rules/missing_space_before_subcommand.py +21 -0
  134. thefuck/rules/mkdir_p.py +13 -0
  135. thefuck/rules/mvn_no_command.py +11 -0
  136. thefuck/rules/mvn_unknown_lifecycle_phase.py +30 -0
  137. thefuck/rules/nixos_cmd_not_found.py +15 -0
  138. thefuck/rules/no_command.py +41 -0
  139. thefuck/rules/no_such_file.py +30 -0
  140. thefuck/rules/npm_missing_script.py +17 -0
  141. thefuck/rules/npm_run_script.py +17 -0
  142. thefuck/rules/npm_wrong_command.py +42 -0
  143. thefuck/rules/omnienv_no_such_command.py +35 -0
  144. thefuck/rules/open.py +40 -0
  145. thefuck/rules/pacman.py +17 -0
  146. thefuck/rules/pacman_invalid_option.py +20 -0
  147. thefuck/rules/pacman_not_found.py +26 -0
  148. thefuck/rules/path_from_history.py +53 -0
  149. thefuck/rules/php_s.py +11 -0
  150. thefuck/rules/pip_install.py +15 -0
  151. thefuck/rules/pip_unknown_command.py +19 -0
  152. thefuck/rules/port_already_in_use.py +40 -0
  153. thefuck/rules/prove_recursively.py +27 -0
  154. thefuck/rules/python_command.py +17 -0
  155. thefuck/rules/python_execute.py +15 -0
  156. thefuck/rules/python_module_error.py +13 -0
  157. thefuck/rules/quotation_marks.py +12 -0
  158. thefuck/rules/rails_migrations_pending.py +14 -0
  159. thefuck/rules/react_native_command_unrecognized.py +34 -0
  160. thefuck/rules/remove_shell_prompt_literal.py +23 -0
  161. thefuck/rules/remove_trailing_cedilla.py +11 -0
  162. thefuck/rules/rm_dir.py +16 -0
  163. thefuck/rules/rm_root.py +16 -0
  164. thefuck/rules/scm_correction.py +32 -0
  165. thefuck/rules/sed_unterminated_s.py +18 -0
  166. thefuck/rules/sl_ls.py +14 -0
  167. thefuck/rules/ssh_known_hosts.py +37 -0
  168. thefuck/rules/sudo.py +47 -0
  169. thefuck/rules/sudo_command_from_user_path.py +21 -0
  170. thefuck/rules/switch_lang.py +117 -0
  171. thefuck/rules/systemctl.py +22 -0
  172. thefuck/rules/terraform_init.py +13 -0
  173. thefuck/rules/terraform_no_command.py +16 -0
  174. thefuck/rules/test.py.py +10 -0
  175. thefuck/rules/tmux.py +18 -0
  176. thefuck/rules/touch.py +14 -0
  177. thefuck/rules/tsuru_login.py +12 -0
  178. thefuck/rules/tsuru_not_command.py +15 -0
  179. thefuck/rules/unknown_command.py +13 -0
  180. thefuck/rules/unsudo.py +15 -0
  181. thefuck/rules/vagrant_up.py +21 -0
  182. thefuck/rules/whois.py +34 -0
  183. thefuck/rules/workon_doesnt_exists.py +32 -0
  184. thefuck/rules/wrong_hyphen_before_subcommand.py +20 -0
  185. thefuck/rules/yarn_alias.py +14 -0
  186. thefuck/rules/yarn_command_not_found.py +43 -0
  187. thefuck/rules/yarn_command_replaced.py +13 -0
  188. thefuck/rules/yarn_help.py +17 -0
  189. thefuck/rules/yum_invalid_operation.py +39 -0
  190. thefuck/shells/__init__.py +52 -0
  191. thefuck/shells/bash.py +94 -0
  192. thefuck/shells/fish.py +131 -0
  193. thefuck/shells/generic.py +154 -0
  194. thefuck/shells/powershell.py +43 -0
  195. thefuck/shells/tcsh.py +44 -0
  196. thefuck/shells/zsh.py +98 -0
  197. thefuck/specific/__init__.py +0 -0
  198. thefuck/specific/apt.py +3 -0
  199. thefuck/specific/archlinux.py +48 -0
  200. thefuck/specific/brew.py +15 -0
  201. thefuck/specific/dnf.py +3 -0
  202. thefuck/specific/git.py +32 -0
  203. thefuck/specific/nix.py +3 -0
  204. thefuck/specific/npm.py +21 -0
  205. thefuck/specific/sudo.py +18 -0
  206. thefuck/specific/yum.py +3 -0
  207. thefuck/system/__init__.py +7 -0
  208. thefuck/system/unix.py +57 -0
  209. thefuck/system/win32.py +43 -0
  210. thefuck/types.py +261 -0
  211. thefuck/ui.py +116 -0
  212. thefuck/utils.py +385 -0
  213. thefuck_leeguoo-3.41.dist-info/METADATA +681 -0
  214. thefuck_leeguoo-3.41.dist-info/RECORD +218 -0
  215. thefuck_leeguoo-3.41.dist-info/WHEEL +6 -0
  216. thefuck_leeguoo-3.41.dist-info/entry_points.txt +3 -0
  217. thefuck_leeguoo-3.41.dist-info/licenses/LICENSE.md +22 -0
  218. thefuck_leeguoo-3.41.dist-info/top_level.txt +1 -0
@@ -0,0 +1,63 @@
1
+ import subprocess
2
+ from thefuck.specific.apt import apt_available
3
+ from thefuck.specific.sudo import sudo_support
4
+ from thefuck.utils import for_app, eager, replace_command
5
+
6
+ enabled_by_default = apt_available
7
+
8
+
9
+ @sudo_support
10
+ @for_app('apt', 'apt-get', 'apt-cache')
11
+ def match(command):
12
+ return 'E: Invalid operation' in command.output
13
+
14
+
15
+ @eager
16
+ def _parse_apt_operations(help_text_lines):
17
+ is_commands_list = False
18
+ for line in help_text_lines:
19
+ line = line.decode().strip()
20
+ if is_commands_list and line:
21
+ yield line.split()[0]
22
+ elif line.startswith('Basic commands:') \
23
+ or line.startswith('Most used commands:'):
24
+ is_commands_list = True
25
+
26
+
27
+ @eager
28
+ def _parse_apt_get_and_cache_operations(help_text_lines):
29
+ is_commands_list = False
30
+ for line in help_text_lines:
31
+ line = line.decode().strip()
32
+ if is_commands_list:
33
+ if not line:
34
+ return
35
+
36
+ yield line.split()[0]
37
+ elif line.startswith('Commands:') \
38
+ or line.startswith('Most used commands:'):
39
+ is_commands_list = True
40
+
41
+
42
+ def _get_operations(app):
43
+ proc = subprocess.Popen([app, '--help'],
44
+ stdout=subprocess.PIPE,
45
+ stderr=subprocess.PIPE)
46
+ lines = proc.stdout.readlines()
47
+
48
+ if app == 'apt':
49
+ return _parse_apt_operations(lines)
50
+ else:
51
+ return _parse_apt_get_and_cache_operations(lines)
52
+
53
+
54
+ @sudo_support
55
+ def get_new_command(command):
56
+ invalid_operation = command.output.split()[-1]
57
+
58
+ if invalid_operation == 'uninstall':
59
+ return [command.script.replace('uninstall', 'remove')]
60
+
61
+ else:
62
+ operations = _get_operations(command.script_parts[0])
63
+ return replace_command(command, invalid_operation, operations)
@@ -0,0 +1,16 @@
1
+ from thefuck.specific.apt import apt_available
2
+ from thefuck.specific.sudo import sudo_support
3
+ from thefuck.utils import for_app
4
+
5
+ enabled_by_default = apt_available
6
+
7
+
8
+ @sudo_support
9
+ @for_app('apt')
10
+ def match(command):
11
+ return 'apt list --upgradable' in command.output
12
+
13
+
14
+ @sudo_support
15
+ def get_new_command(command):
16
+ return 'apt list --upgradable'
@@ -0,0 +1,16 @@
1
+ from thefuck.specific.apt import apt_available
2
+ from thefuck.specific.sudo import sudo_support
3
+ from thefuck.utils import for_app
4
+
5
+ enabled_by_default = apt_available
6
+
7
+
8
+ @sudo_support
9
+ @for_app('apt')
10
+ def match(command):
11
+ return command.script == "apt list --upgradable" and len(command.output.strip().split('\n')) > 1
12
+
13
+
14
+ @sudo_support
15
+ def get_new_command(command):
16
+ return 'apt upgrade'
@@ -0,0 +1,17 @@
1
+ import re
2
+
3
+ from thefuck.utils import for_app, replace_argument
4
+
5
+ INVALID_CHOICE = "(?<=Invalid choice: ')(.*)(?=', maybe you meant:)"
6
+ OPTIONS = "^\\s*\\*\\s(.*)"
7
+
8
+
9
+ @for_app('aws')
10
+ def match(command):
11
+ return "usage:" in command.output and "maybe you meant:" in command.output
12
+
13
+
14
+ def get_new_command(command):
15
+ mistake = re.search(INVALID_CHOICE, command.output).group(0)
16
+ options = re.findall(OPTIONS, command.output, flags=re.MULTILINE)
17
+ return [replace_argument(command.script, mistake, o) for o in options]
@@ -0,0 +1,17 @@
1
+ import re
2
+
3
+ from thefuck.utils import for_app, replace_argument
4
+
5
+ INVALID_CHOICE = "(?=az)(?:.*): '(.*)' is not in the '.*' command group."
6
+ OPTIONS = "^The most similar choice to '.*' is:\n\\s*(.*)$"
7
+
8
+
9
+ @for_app('az')
10
+ def match(command):
11
+ return "is not in the" in command.output and "command group" in command.output
12
+
13
+
14
+ def get_new_command(command):
15
+ mistake = re.search(INVALID_CHOICE, command.output).group(1)
16
+ options = re.findall(OPTIONS, command.output, flags=re.MULTILINE)
17
+ return [replace_argument(command.script, mistake, o) for o in options]
@@ -0,0 +1,33 @@
1
+ from thefuck.utils import for_app, eager
2
+ from thefuck.shells import shell
3
+ from thefuck.specific.brew import brew_available
4
+
5
+
6
+ @for_app('brew')
7
+ def match(command):
8
+ return (u'install' in command.script_parts
9
+ and u'brew cask install' in command.output)
10
+
11
+
12
+ @eager
13
+ def _get_cask_install_lines(output):
14
+ for line in output.split('\n'):
15
+ line = line.strip()
16
+ if line.startswith('brew cask install'):
17
+ yield line
18
+
19
+
20
+ def _get_script_for_brew_cask(output):
21
+ cask_install_lines = _get_cask_install_lines(output)
22
+ if len(cask_install_lines) > 1:
23
+ return shell.and_(*cask_install_lines)
24
+ else:
25
+ return cask_install_lines[0]
26
+
27
+
28
+ def get_new_command(command):
29
+ brew_cask_script = _get_script_for_brew_cask(command.output)
30
+ return shell.and_(brew_cask_script, command.script)
31
+
32
+
33
+ enabled_by_default = brew_available
@@ -0,0 +1,24 @@
1
+ import re
2
+ from thefuck.utils import for_app
3
+ from thefuck.specific.brew import brew_available
4
+
5
+ enabled_by_default = brew_available
6
+
7
+
8
+ def _get_suggestions(str):
9
+ suggestions = str.replace(" or ", ", ").split(", ")
10
+ return suggestions
11
+
12
+
13
+ @for_app('brew', at_least=2)
14
+ def match(command):
15
+ is_proper_command = ('install' in command.script and
16
+ 'No available formula' in command.output and
17
+ 'Did you mean' in command.output)
18
+ return is_proper_command
19
+
20
+
21
+ def get_new_command(command):
22
+ matcher = re.search('Warning: No available formula with the name "(?:[^"]+)". Did you mean (.+)\\?', command.output)
23
+ suggestions = _get_suggestions(matcher.group(1))
24
+ return ["brew install " + formula for formula in suggestions]
@@ -0,0 +1,15 @@
1
+ from thefuck.utils import for_app
2
+
3
+
4
+ @for_app('brew', at_least=2)
5
+ def match(command):
6
+ return (command.script_parts[1] in ['ln', 'link']
7
+ and "brew link --overwrite --dry-run" in command.output)
8
+
9
+
10
+ def get_new_command(command):
11
+ command_parts = command.script_parts[:]
12
+ command_parts[1] = 'link'
13
+ command_parts.insert(2, '--overwrite')
14
+ command_parts.insert(3, '--dry-run')
15
+ return ' '.join(command_parts)
@@ -0,0 +1,19 @@
1
+ import re
2
+ from thefuck.utils import for_app
3
+
4
+
5
+ warning_regex = re.compile(r'Warning: (?:.(?!is ))+ is already installed and '
6
+ r'up-to-date')
7
+ message_regex = re.compile(r'To reinstall (?:(?!, ).)+, run `brew reinstall '
8
+ r'[^`]+`')
9
+
10
+
11
+ @for_app('brew', at_least=2)
12
+ def match(command):
13
+ return ('install' in command.script
14
+ and warning_regex.search(command.output)
15
+ and message_regex.search(command.output))
16
+
17
+
18
+ def get_new_command(command):
19
+ return command.script.replace('install', 'reinstall')
@@ -0,0 +1,14 @@
1
+ from thefuck.utils import for_app
2
+
3
+
4
+ @for_app('brew', at_least=2)
5
+ def match(command):
6
+ return (command.script_parts[1] in ['uninstall', 'rm', 'remove']
7
+ and "brew uninstall --force" in command.output)
8
+
9
+
10
+ def get_new_command(command):
11
+ command_parts = command.script_parts[:]
12
+ command_parts[1] = 'uninstall'
13
+ command_parts.insert(2, '--force')
14
+ return ' '.join(command_parts)
@@ -0,0 +1,82 @@
1
+ import os
2
+ import re
3
+ from thefuck.utils import get_closest, replace_command
4
+ from thefuck.specific.brew import get_brew_path_prefix, brew_available
5
+
6
+ BREW_CMD_PATH = '/Homebrew/Library/Homebrew/cmd'
7
+ TAP_PATH = '/Homebrew/Library/Taps'
8
+ TAP_CMD_PATH = '/%s/%s/cmd'
9
+
10
+ enabled_by_default = brew_available
11
+
12
+
13
+ def _get_brew_commands(brew_path_prefix):
14
+ """To get brew default commands on local environment"""
15
+ brew_cmd_path = brew_path_prefix + BREW_CMD_PATH
16
+
17
+ return [name[:-3] for name in os.listdir(brew_cmd_path)
18
+ if name.endswith(('.rb', '.sh'))]
19
+
20
+
21
+ def _get_brew_tap_specific_commands(brew_path_prefix):
22
+ """To get tap's specific commands
23
+ https://github.com/Homebrew/homebrew/blob/master/Library/brew.rb#L115"""
24
+ commands = []
25
+ brew_taps_path = brew_path_prefix + TAP_PATH
26
+
27
+ for user in _get_directory_names_only(brew_taps_path):
28
+ taps = _get_directory_names_only(brew_taps_path + '/%s' % user)
29
+
30
+ # Brew Taps's naming rule
31
+ # https://github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/brew-tap.md#naming-conventions-and-limitations
32
+ taps = (tap for tap in taps if tap.startswith('homebrew-'))
33
+ for tap in taps:
34
+ tap_cmd_path = brew_taps_path + TAP_CMD_PATH % (user, tap)
35
+
36
+ if os.path.isdir(tap_cmd_path):
37
+ commands += (name.replace('brew-', '').replace('.rb', '')
38
+ for name in os.listdir(tap_cmd_path)
39
+ if _is_brew_tap_cmd_naming(name))
40
+
41
+ return commands
42
+
43
+
44
+ def _is_brew_tap_cmd_naming(name):
45
+ return name.startswith('brew-') and name.endswith('.rb')
46
+
47
+
48
+ def _get_directory_names_only(path):
49
+ return [d for d in os.listdir(path)
50
+ if os.path.isdir(os.path.join(path, d))]
51
+
52
+
53
+ def _brew_commands():
54
+ brew_path_prefix = get_brew_path_prefix()
55
+ if brew_path_prefix:
56
+ try:
57
+ return (_get_brew_commands(brew_path_prefix)
58
+ + _get_brew_tap_specific_commands(brew_path_prefix))
59
+ except OSError:
60
+ pass
61
+
62
+ # Failback commands for testing (Based on Homebrew 0.9.5)
63
+ return ['info', 'home', 'options', 'install', 'uninstall',
64
+ 'search', 'list', 'update', 'upgrade', 'pin', 'unpin',
65
+ 'doctor', 'create', 'edit', 'cask']
66
+
67
+
68
+ def match(command):
69
+ is_proper_command = ('brew' in command.script and
70
+ 'Unknown command' in command.output)
71
+
72
+ if is_proper_command:
73
+ broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)',
74
+ command.output)[0]
75
+ return bool(get_closest(broken_cmd, _brew_commands()))
76
+ return False
77
+
78
+
79
+ def get_new_command(command):
80
+ broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)',
81
+ command.output)[0]
82
+ return replace_command(command, broken_cmd, _brew_commands())
@@ -0,0 +1,12 @@
1
+ from thefuck.utils import for_app
2
+
3
+
4
+ @for_app('brew', at_least=2)
5
+ def match(command):
6
+ return ('update' in command.script
7
+ and "Error: This command updates brew itself" in command.output
8
+ and "Use `brew upgrade" in command.output)
9
+
10
+
11
+ def get_new_command(command):
12
+ return command.script.replace('update', 'upgrade')
thefuck/rules/cargo.py ADDED
@@ -0,0 +1,6 @@
1
+ def match(command):
2
+ return command.script == 'cargo'
3
+
4
+
5
+ def get_new_command(command):
6
+ return 'cargo build'
@@ -0,0 +1,15 @@
1
+ import re
2
+ from thefuck.utils import replace_argument, for_app
3
+
4
+
5
+ @for_app('cargo', at_least=1)
6
+ def match(command):
7
+ return ('no such subcommand' in command.output.lower()
8
+ and 'Did you mean' in command.output)
9
+
10
+
11
+ def get_new_command(command):
12
+ broken = command.script_parts[1]
13
+ fix = re.findall(r'Did you mean `([^`]*)`', command.output)[0]
14
+
15
+ return replace_argument(command.script, broken, fix)
@@ -0,0 +1,14 @@
1
+ import os
2
+ from thefuck.utils import for_app
3
+
4
+
5
+ @for_app('cat', at_least=1)
6
+ def match(command):
7
+ return (
8
+ command.output.startswith('cat: ') and
9
+ os.path.isdir(command.script_parts[1])
10
+ )
11
+
12
+
13
+ def get_new_command(command):
14
+ return command.script.replace('cat', 'ls', 1)
@@ -0,0 +1,61 @@
1
+ """Attempts to spellcheck and correct failed cd commands"""
2
+
3
+ import os
4
+ import six
5
+ from thefuck.specific.sudo import sudo_support
6
+ from thefuck.rules import cd_mkdir
7
+ from thefuck.utils import for_app, get_close_matches
8
+
9
+ __author__ = "mmussomele"
10
+
11
+ MAX_ALLOWED_DIFF = 0.6
12
+
13
+
14
+ def _get_sub_dirs(parent):
15
+ """Returns a list of the child directories of the given parent directory"""
16
+ return [child for child in os.listdir(parent) if os.path.isdir(os.path.join(parent, child))]
17
+
18
+
19
+ @sudo_support
20
+ @for_app('cd')
21
+ def match(command):
22
+ """Match function copied from cd_mkdir.py"""
23
+ return (
24
+ command.script.startswith('cd ') and any((
25
+ 'no such file or directory' in command.output.lower(),
26
+ 'cd: can\'t cd to' in command.output.lower(),
27
+ 'does not exist' in command.output.lower()
28
+ )))
29
+
30
+
31
+ @sudo_support
32
+ def get_new_command(command):
33
+ """
34
+ Attempt to rebuild the path string by spellchecking the directories.
35
+ If it fails (i.e. no directories are a close enough match), then it
36
+ defaults to the rules of cd_mkdir.
37
+ Change sensitivity by changing MAX_ALLOWED_DIFF. Default value is 0.6
38
+ """
39
+ dest = command.script_parts[1].split(os.sep)
40
+ if dest[-1] == '':
41
+ dest = dest[:-1]
42
+
43
+ if dest[0] == '':
44
+ cwd = os.sep
45
+ dest = dest[1:]
46
+ elif six.PY2:
47
+ cwd = os.getcwdu()
48
+ else:
49
+ cwd = os.getcwd()
50
+ for directory in dest:
51
+ if directory == ".":
52
+ continue
53
+ elif directory == "..":
54
+ cwd = os.path.split(cwd)[0]
55
+ continue
56
+ best_matches = get_close_matches(directory, _get_sub_dirs(cwd), cutoff=MAX_ALLOWED_DIFF)
57
+ if best_matches:
58
+ cwd = os.path.join(cwd, best_matches[0])
59
+ else:
60
+ return cd_mkdir.get_new_command(command)
61
+ return u'cd "{0}"'.format(cwd)
thefuck/rules/cd_cs.py ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ # Redirects cs to cd when there is a typo
4
+ # Due to the proximity of the keys - d and s - this seems like a common typo
5
+ # ~ > cs /etc/
6
+ # cs: command not found
7
+ # ~ > fuck
8
+ # cd /etc/ [enter/↑/↓/ctrl+c]
9
+ # /etc >
10
+
11
+
12
+ def match(command):
13
+ if command.script_parts[0] == 'cs':
14
+ return True
15
+
16
+
17
+ def get_new_command(command):
18
+ return 'cd' + ''.join(command.script[2:])
19
+
20
+
21
+ priority = 900
@@ -0,0 +1,21 @@
1
+ import re
2
+ from thefuck.utils import for_app
3
+ from thefuck.specific.sudo import sudo_support
4
+ from thefuck.shells import shell
5
+
6
+
7
+ @sudo_support
8
+ @for_app('cd')
9
+ def match(command):
10
+ return (
11
+ command.script.startswith('cd ') and any((
12
+ 'no such file or directory' in command.output.lower(),
13
+ 'cd: can\'t cd to' in command.output.lower(),
14
+ 'does not exist' in command.output.lower()
15
+ )))
16
+
17
+
18
+ @sudo_support
19
+ def get_new_command(command):
20
+ repl = shell.and_('mkdir -p \\1', 'cd \\1')
21
+ return re.sub(r'^cd (.*)', repl, command.script)
@@ -0,0 +1,16 @@
1
+ # Adds the missing space between the cd command and the target directory
2
+ # when trying to cd to the parent directory.
3
+ #
4
+ # Does not really save chars, but is fun :D
5
+ #
6
+ # Example:
7
+ # > cd..
8
+ # cd..: command not found
9
+
10
+
11
+ def match(command):
12
+ return command.script == 'cd..'
13
+
14
+
15
+ def get_new_command(command):
16
+ return 'cd ..'
@@ -0,0 +1,15 @@
1
+ import os
2
+ from thefuck.shells import shell
3
+
4
+
5
+ def match(command):
6
+ return (command.script.startswith('./')
7
+ and 'permission denied' in command.output.lower()
8
+ and os.path.exists(command.script_parts[0])
9
+ and not os.access(command.script_parts[0], os.X_OK))
10
+
11
+
12
+ def get_new_command(command):
13
+ return shell.and_(
14
+ 'chmod +x {}'.format(command.script_parts[0][2:]),
15
+ command.script)
@@ -0,0 +1,25 @@
1
+ from thefuck.utils import for_app, which
2
+
3
+
4
+ @for_app("choco", "cinst")
5
+ def match(command):
6
+ return ((command.script.startswith('choco install') or 'cinst' in command.script_parts)
7
+ and 'Installing the following packages' in command.output)
8
+
9
+
10
+ def get_new_command(command):
11
+ # Find the argument that is the package name
12
+ for script_part in command.script_parts:
13
+ if (
14
+ script_part not in ["choco", "cinst", "install"]
15
+ # Need exact match (bc chocolatey is a package)
16
+ and not script_part.startswith('-')
17
+ # Leading hyphens are parameters; some packages contain them though
18
+ and '=' not in script_part and '/' not in script_part
19
+ # These are certainly parameters
20
+ ):
21
+ return command.script.replace(script_part, script_part + ".install")
22
+ return []
23
+
24
+
25
+ enabled_by_default = bool(which("choco")) or bool(which("cinst"))
@@ -0,0 +1,22 @@
1
+ import re
2
+ from thefuck.utils import replace_argument, for_app
3
+
4
+
5
+ @for_app('composer')
6
+ def match(command):
7
+ return (('did you mean this?' in command.output.lower()
8
+ or 'did you mean one of these?' in command.output.lower())) or (
9
+ "install" in command.script_parts and "composer require" in command.output.lower()
10
+ )
11
+
12
+
13
+ def get_new_command(command):
14
+ if "install" in command.script_parts and "composer require" in command.output.lower():
15
+ broken_cmd, new_cmd = "install", "require"
16
+ else:
17
+ broken_cmd = re.findall(r"Command \"([^']*)\" is not defined", command.output)[0]
18
+ new_cmd = re.findall(r'Did you mean this\?[^\n]*\n\s*([^\n]*)', command.output)
19
+ if not new_cmd:
20
+ new_cmd = re.findall(r'Did you mean one of these\?[^\n]*\n\s*([^\n]*)', command.output)
21
+ new_cmd = new_cmd[0].strip()
22
+ return replace_argument(command.script, broken_cmd, new_cmd)
@@ -0,0 +1,17 @@
1
+ import re
2
+ from thefuck.utils import replace_command, for_app
3
+
4
+
5
+ @for_app("conda")
6
+ def match(command):
7
+ """
8
+ Match a mistyped command
9
+ """
10
+ return "Did you mean 'conda" in command.output
11
+
12
+
13
+ def get_new_command(command):
14
+ match = re.findall(r"'conda ([^']*)'", command.output)
15
+ broken_cmd = match[0]
16
+ correct_cmd = match[1]
17
+ return replace_command(command, broken_cmd, [correct_cmd])
@@ -0,0 +1,15 @@
1
+ from thefuck.shells import shell
2
+ from thefuck.utils import for_app
3
+
4
+
5
+ @for_app("cp", "mv")
6
+ def match(command):
7
+ return (
8
+ "No such file or directory" in command.output
9
+ or command.output.startswith("cp: directory")
10
+ and command.output.rstrip().endswith("does not exist")
11
+ )
12
+
13
+
14
+ def get_new_command(command):
15
+ return shell.and_(u"mkdir -p {}".format(command.script_parts[-1]), command.script)
@@ -0,0 +1,15 @@
1
+ import re
2
+ from thefuck.specific.sudo import sudo_support
3
+ from thefuck.utils import for_app
4
+
5
+
6
+ @sudo_support
7
+ @for_app('cp')
8
+ def match(command):
9
+ output = command.output.lower()
10
+ return 'omitting directory' in output or 'is a directory' in output
11
+
12
+
13
+ @sudo_support
14
+ def get_new_command(command):
15
+ return re.sub(r'^cp', 'cp -a', command.script)
thefuck/rules/cpp11.py ADDED
@@ -0,0 +1,12 @@
1
+ from thefuck.utils import for_app
2
+
3
+
4
+ @for_app('g++', 'clang++')
5
+ def match(command):
6
+ return ('This file requires compiler and library support for the '
7
+ 'ISO C++ 2011 standard.' in command.output or
8
+ '-Wc++11-extensions' in command.output)
9
+
10
+
11
+ def get_new_command(command):
12
+ return command.script + ' -std=c++11'