Linux/thefuck: Difference between revisions

From Omnia
Jump to navigation Jump to search
 
Line 9: Line 9:


  "Magnificent app which corrects your previous console command."
  "Magnificent app which corrects your previous console command."
== alternative - pay-respects ==
See [[linux/pay-respects]]


== Installation ==
== Installation ==

Latest revision as of 07:12, 13 April 2025

thefuck

dead project, but very useful. See linux/pay-respects as an alternative.

Broken with newer python environments like Python 3.12 (which you would find on Ubuntu 24.04).

thefuck
https://github.com/nvbn/thefuck
"Magnificent app which corrects your previous console command."

alternative - pay-respects

See linux/pay-respects

Installation

sudo apt update
sudo apt install python3-dev python3-pip python3-setuptools
pip3 install thefuck --user

Add to ~/.bashrc:

# thefuck
export PATH=$PATH:~/.local/bin
eval "$(thefuck --alias)"
alias fck=fuck
alias oops=fuck
alias nuts=fuck
alias duck=fuck
alias F=fuck

With Pay-Respects

# Pay-Respects
# https://codeberg.org/iff/pay-respects
export PATH=$PATH:~/.local/bin
eval "$(pay-respects bash --alias)"

# thefuck
#export PATH=$PATH:~/.local/bin
eval "$(thefuck --alias)"

fix for python 3.12

Having a hard time getting set up on Ubuntu 24.04 · Issue #1449 · nvbn/thefuck · GitHub
https://github.com/nvbn/thefuck/issues/1449#issuecomment-2137634221

Add to .bashrc:

export PATH=$PATH:~/.local/bin
eval "$(thefuck --alias)"

quick fix for pip installed version at least:

Create venv:

python3 -m venv ~/.local --system-site-packages

Install thefuck:

. ~/.local/bin/activate
pip install thefuck

-

open ~/.local/lib/python3.12/site-packages/thefuck/conf.py

replace line:

from imp import load_source

with:

import importlib.machinery

and lines:

settings = load_source(
    'settings', text_type(self.user_dir.joinpath('settings.py')))

with:

settings = importlib.machinery.SourceFileLoader(
        'settings', text_type(self.user_dir.joinpath('settings.py'))).load_module()

-

then open ~/.local/lib/python3.12/site-packages/thefuck/types.py

replace import statement as above:

from imp import load_source

with:

import importlib.machinery

and line:

rule_module = load_source(name, str(path))

with:

rule_module = importlib.machinery.SourceFileLoader(name, str(path)).load_module()

-

This worked for me on Fedora 40 using fish shell in tilix terminal emulator, can't say for any other combination.

-

thefuck-py312.patch

diff -Naur lib/python3.12/site-packages/thefuck/conf.py.old lib/python3.12/site-packages/thefuck/conf.py
--- lib/python3.12/site-packages/thefuck/conf.py.old    2025-04-12 23:53:14.623927863 -0700
+++ lib/python3.12/site-packages/thefuck/conf.py        2025-04-12 23:54:16.703423403 -0700
@@ -1,4 +1,5 @@
-from imp import load_source
+# from imp import load_source
+import importlib.machinery
 import os
 import sys
 from warnings import warn
@@ -66,8 +67,10 @@

     def _settings_from_file(self):
         """Loads settings from file."""
-        settings = load_source(
-            'settings', text_type(self.user_dir.joinpath('settings.py')))
+        # settings = load_source(
+        #     'settings', text_type(self.user_dir.joinpath('settings.py')))
+        settings = importlib.machinery.SourceFileLoader(
+                'settings', text_type(self.user_dir.joinpath('settings.py'))).load_module()
         return {key: getattr(settings, key)
                 for key in const.DEFAULT_SETTINGS.keys()
                 if hasattr(settings, key)}
diff -Naur lib/python3.12/site-packages/thefuck/types.py.old lib/python3.12/site-packages/thefuck/types.py
--- lib/python3.12/site-packages/thefuck/types.py.old   2025-04-12 23:53:26.438831850 -0700
+++ lib/python3.12/site-packages/thefuck/types.py       2025-04-12 23:54:48.944161438 -0700
@@ -1,4 +1,5 @@
-from imp import load_source
+# from imp import load_source
+import importlib.machinery
 import os
 import sys
 from . import logs
@@ -141,7 +142,8 @@
             return
         with logs.debug_time(u'Importing rule: {};'.format(name)):
             try:
-                rule_module = load_source(name, str(path))
+                # rule_module = load_source(name, str(path))
+                rule_module = importlib.machinery.SourceFileLoader(name, str(path)).load_module()
             except Exception:
                 logs.exception(u"Rule {} failed to load".format(name), sys.exc_info())
                 return
cd ~/.fck
patch -p0 < ~/patch

-

This will solve this error:

(.fck) kenneth@lmt-srv-114:~$ /home/user/.fck/bin/thefuck
Traceback (most recent call last):
  File "/home/user/.fck/bin/thefuck", line 5, in <module>
    from thefuck.entrypoints.main import main
  File "/home/user/.fck/lib/python3.12/site-packages/thefuck/entrypoints/main.py", line 8, in <module>
    from .. import logs  # noqa: E402
    ^^^^^^^^^^^^^^^^^^^
  File "/home/user/.fck/lib/python3.12/site-packages/thefuck/logs.py", line 8, in <module>
    from .conf import settings
  File "/home/user/.fck/lib/python3.12/site-packages/thefuck/conf.py", line 1, in <module>
    from imp import load_source
ModuleNotFoundError: No module named 'imp'

disutils missing error

$ thefuck
Traceback (most recent call last):
  File "/home/user/.src/thefuck/bin/thefuck", line 5, in <module>
    from thefuck.entrypoints.main import main
  File "/home/user/.src/thefuck/lib/python3.12/site-packages/thefuck/entrypoints/main.py", line 2, in <module>
    from ..system import init_output
  File "/home/user/.src/thefuck/lib/python3.12/site-packages/thefuck/system/__init__.py", line 7, in <module>
    from .unix import *  # noqa: F401,F403
    ^^^^^^^^^^^^^^^^^^^
  File "/home/user/.src/thefuck/lib/python3.12/site-packages/thefuck/system/unix.py", line 6, in <module>
    from distutils.spawn import find_executable
ModuleNotFoundError: No module named 'distutils'

When you create the venv make sure to include the system python

python3 -m venv ~/.local --system-site-packages

clean version

Edit:

/usr/local/lib/python3.10/dist-packages/thefuck/ui.py

    try:
        selector = CommandSelector(corrected_commands)
    except NoRuleMatched:
        logs.failed('No fucks given' if get_alias() == 'fuck'
                    else 'Nothing found')

to something like:

    except NoRuleMatched:
        logs.failed('No ducks given' if get_alias() == 'fuck'
                    else 'Nothing found')
eval "$(thefuck --alias)"
alias fck=fuck
alias oops=fuck
alias nuts=fuck
alias duck=fuck
alias F=fuck

keywords