Skip to content

Repository files navigation

Crate

refac: Automatically edit text.

The workflow:

  • Select some text.
  • Run the command, write instructions on what you want changed.
  • Enjoy the sassy comments.

Calls Claude by default — bring your own key and run refac login (or set ANTHROPIC_API_KEY). For OpenAI, set REFAC_PROVIDER=openai and OPENAI_API_KEY. Optional provider / model config lives in ~/.config/refac/config.toml.

SETUP

# This tool can be installed using cargo.
cargo install refac
# Enter your api key it will be saved to your drive for future use.
refac login

Try it out

> refac tor 'The quick brown fox jumps over the lazy dog.''convert to all caps'
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.
> refac tor 'def add(a: int, b: int): return a + b''turn this into a command line program that accepts a and b as arguments, printing the result'# Another riveting addition machine for the ages. I'll spruce it up with type hints and argparse,# because apparently I have standards even when you don't.# Run it with `python add.py <a> <b>`.# --refac
import argparse
def add(a: int, b: int) -> int:
return a + b
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Add two integers.")
parser.add_argument("a", type=int, help="The first integer.")
parser.add_argument("b", type=int, help="The second integer.")
args = parser.parse_args()
print(add(args.a, args.b))
> refac tor 'fn factorial(a: usize) -> usize { if a <= 1 { 1 } else { a * factorial(a - 1) }}''switch to an iterative implementation'
// Recursion is elegant and all, but why summon the stack-overflow goblins when a loop will do?
// Here's your iterative factorial, served fresh.// --refacfn factorial(a: usize) -> usize { let mut result = 1; for i in 2..=a { result *= i; } result}> refac tor '
fn factorial(a: usize) -> usize {
let mut result = 1;foriin 1..=a {
result *= i;
}
result
}
''use an iterator and .fold()'// Look at you, embracing the functional style! I'm getting all warm and fuzzy inside.
// --refac
fn factorial(a: usize) -> usize {
(1..=a).fold(1, |result, i| result * i)
}
> refac tor '''implement hello world in rust'
// Behold! A masterpiece of unparalleled complexity. Try not to strain yourself.
// --refac
fn main() {
println!("Hello, world!");
}
> refac tor '''write fizzbuzz in rust'
// FizzBuzz, the eternal rite of passage. You've ascended to junior dev status, congrats.// --refacfn main() { for i in 1..=100 { match (i % 3, i % 5) { (0, 0) => println!("FizzBuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } }}> refac tor '
Hey [Name],
I'm writing to ask if you can lend me $100. I promise I'll pay you back as soon as possible.
Thanks,
[Your Name]
''make the email more formal and appropriate for a professional setting'Dear [Name],I hope this message finds you well. I am writing to respectfully request a short-term loan of $100. I would be most grateful for your assistance, and I assure you that I will repay the amount at the earliest possible opportunity.Please let me know if this is something you would be willing to consider. I am happy to discuss any terms or arrangements that would be convenient for you.Thank you very much for your time and consideration.Best regards,[Your Name]

Using Refac From Your Favorite Text Editor

First, make sure you have:

  • installed refac
  • entered your API key using refac login

Emacs

After installing and logging in add this chunk of flim-flam to your init.el:

Note this code assumes init.el is using lexical-binding. Make sure ;; -*- lexical-binding: t -*- is added to the top of init.el. Otherwise the following code won't work.

(defunrefac-call-executable-async (selected-texttransformcallback)
"Asynchronously call the refac executable, passing SELECTED-TEXT and TRANSFORM.CALLBACK is a function taking two parameters: EXIT-STATUS and RESULT."
(let ((refac-executable (executable-find"refac"))
(temp-buf (generate-new-buffer"*refac-output*")))
(if refac-executable
(make-process:name"refac-async":buffer temp-buf
:command (list refac-executable "tor" selected-text transform)
:sentinel
(lambda (proc_event)
(when (memq (process-status proc) '(exit signal))
(let ((buf (process-buffer proc)))
;; Ensure the buffer is still alive before attempting to read from it
(when (buffer-live-p buf)
(with-current-buffer buf
(let ((exit-status (process-exit-status proc))
(result (buffer-string)))
(kill-buffer buf)
(funcall callback exit-status result))))))))
(error"refac executable not found"))))
(global-set-key (kbd"C-c r") 'refac)
(defunrefac (begendtransform)
"Perform the refac transform in place, inserting merge markers inline, asynchronously.The overlay will display the transform prompt until the results arrive."
(interactive"r\nMTransform: ")
(let* ((buffer (current-buffer))
(original-text (buffer-substring-no-properties beg end))
;; Insert merge markers.
(_ (goto-char end))
(_ (insert"\n=======\n\n"))
(overlay (make-overlay (- (point) 1) (point) buffer tnil))
(_ (insert">>>>>>> TRANSFORMED\n"))
(_ (goto-char beg))
(_ (insert"<<<<<<< ORIGINAL\n"))
(_ (smerge-mode1)))
;; Show the transform prompt in the overlay until the async call finishes.
(overlay-put overlay 'display
(concat"Running refac...\nTransform: " transform "\n"))
(refac-call-executable-async
original-text
transform
(lambda (exit-statusresult)
(with-current-buffer buffer
(let ((saved-point (point)))
(goto-char (overlay-start overlay))
;; Once results arrive, we remove the overlay and insert the result.
(delete-overlay overlay)
(insert result)
(goto-char saved-point)
(unless (zerop exit-status)
(error"refac returned a non-zero exit status: %d. Error: %s"
exit-status result))))))))

And bind the function to a key if you like that sort of thing.

(global-set-key (kbd"C-c r") 'refac)

Not Emacs

Your contrubutions are welcome!

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Apply arbitrary transformations to text via an LLM.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - bddap/refac: Apply arbitrary transformations to text via an LLM. · GitHub
Skip to content

Repository files navigation

Crate

refac: Automatically edit text.

The workflow:

  • Select some text.
  • Run the command, write instructions on what you want changed.
  • Enjoy the sassy comments.

Calls Claude by default — bring your own key and run refac login (or set ANTHROPIC_API_KEY). For OpenAI, set REFAC_PROVIDER=openai and OPENAI_API_KEY. Optional provider / model config lives in ~/.config/refac/config.toml.

SETUP

# This tool can be installed using cargo.
cargo install refac
# Enter your api key it will be saved to your drive for future use.
refac login

Try it out

> refac tor 'The quick brown fox jumps over the lazy dog.''convert to all caps'
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.
> refac tor 'def add(a: int, b: int): return a + b''turn this into a command line program that accepts a and b as arguments, printing the result'# Another riveting addition machine for the ages. I'll spruce it up with type hints and argparse,# because apparently I have standards even when you don't.# Run it with `python add.py <a> <b>`.# --refac
import argparse
def add(a: int, b: int) -> int:
return a + b
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Add two integers.")
parser.add_argument("a", type=int, help="The first integer.")
parser.add_argument("b", type=int, help="The second integer.")
args = parser.parse_args()
print(add(args.a, args.b))
> refac tor 'fn factorial(a: usize) -> usize { if a <= 1 { 1 } else { a * factorial(a - 1) }}''switch to an iterative implementation'
// Recursion is elegant and all, but why summon the stack-overflow goblins when a loop will do?
// Here's your iterative factorial, served fresh.// --refacfn factorial(a: usize) -> usize { let mut result = 1; for i in 2..=a { result *= i; } result}> refac tor '
fn factorial(a: usize) -> usize {
let mut result = 1;foriin 1..=a {
result *= i;
}
result
}
''use an iterator and .fold()'// Look at you, embracing the functional style! I'm getting all warm and fuzzy inside.
// --refac
fn factorial(a: usize) -> usize {
(1..=a).fold(1, |result, i| result * i)
}
> refac tor '''implement hello world in rust'
// Behold! A masterpiece of unparalleled complexity. Try not to strain yourself.
// --refac
fn main() {
println!("Hello, world!");
}
> refac tor '''write fizzbuzz in rust'
// FizzBuzz, the eternal rite of passage. You've ascended to junior dev status, congrats.// --refacfn main() { for i in 1..=100 { match (i % 3, i % 5) { (0, 0) => println!("FizzBuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } }}> refac tor '
Hey [Name],
I'm writing to ask if you can lend me $100. I promise I'll pay you back as soon as possible.
Thanks,
[Your Name]
''make the email more formal and appropriate for a professional setting'Dear [Name],I hope this message finds you well. I am writing to respectfully request a short-term loan of $100. I would be most grateful for your assistance, and I assure you that I will repay the amount at the earliest possible opportunity.Please let me know if this is something you would be willing to consider. I am happy to discuss any terms or arrangements that would be convenient for you.Thank you very much for your time and consideration.Best regards,[Your Name]

Using Refac From Your Favorite Text Editor

First, make sure you have:

  • installed refac
  • entered your API key using refac login

Emacs

After installing and logging in add this chunk of flim-flam to your init.el:

Note this code assumes init.el is using lexical-binding. Make sure ;; -*- lexical-binding: t -*- is added to the top of init.el. Otherwise the following code won't work.

(defunrefac-call-executable-async (selected-texttransformcallback)
"Asynchronously call the refac executable, passing SELECTED-TEXT and TRANSFORM.CALLBACK is a function taking two parameters: EXIT-STATUS and RESULT."
(let ((refac-executable (executable-find"refac"))
(temp-buf (generate-new-buffer"*refac-output*")))
(if refac-executable
(make-process:name"refac-async":buffer temp-buf
:command (list refac-executable "tor" selected-text transform)
:sentinel
(lambda (proc_event)
(when (memq (process-status proc) '(exit signal))
(let ((buf (process-buffer proc)))
;; Ensure the buffer is still alive before attempting to read from it
(when (buffer-live-p buf)
(with-current-buffer buf
(let ((exit-status (process-exit-status proc))
(result (buffer-string)))
(kill-buffer buf)
(funcall callback exit-status result))))))))
(error"refac executable not found"))))
(global-set-key (kbd"C-c r") 'refac)
(defunrefac (begendtransform)
"Perform the refac transform in place, inserting merge markers inline, asynchronously.The overlay will display the transform prompt until the results arrive."
(interactive"r\nMTransform: ")
(let* ((buffer (current-buffer))
(original-text (buffer-substring-no-properties beg end))
;; Insert merge markers.
(_ (goto-char end))
(_ (insert"\n=======\n\n"))
(overlay (make-overlay (- (point) 1) (point) buffer tnil))
(_ (insert">>>>>>> TRANSFORMED\n"))
(_ (goto-char beg))
(_ (insert"<<<<<<< ORIGINAL\n"))
(_ (smerge-mode1)))
;; Show the transform prompt in the overlay until the async call finishes.
(overlay-put overlay 'display
(concat"Running refac...\nTransform: " transform "\n"))
(refac-call-executable-async
original-text
transform
(lambda (exit-statusresult)
(with-current-buffer buffer
(let ((saved-point (point)))
(goto-char (overlay-start overlay))
;; Once results arrive, we remove the overlay and insert the result.
(delete-overlay overlay)
(insert result)
(goto-char saved-point)
(unless (zerop exit-status)
(error"refac returned a non-zero exit status: %d. Error: %s"
exit-status result))))))))

And bind the function to a key if you like that sort of thing.

(global-set-key (kbd"C-c r") 'refac)

Not Emacs

Your contrubutions are welcome!

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Apply arbitrary transformations to text via an LLM.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - bddap/refac: Apply arbitrary transformations to text via an LLM. · GitHub
Skip to content

Repository files navigation

Crate

refac: Automatically edit text.

The workflow:

  • Select some text.
  • Run the command, write instructions on what you want changed.
  • Enjoy the sassy comments.

Calls Claude by default — bring your own key and run refac login (or set ANTHROPIC_API_KEY). For OpenAI, set REFAC_PROVIDER=openai and OPENAI_API_KEY. Optional provider / model config lives in ~/.config/refac/config.toml.

SETUP

# This tool can be installed using cargo.
cargo install refac
# Enter your api key it will be saved to your drive for future use.
refac login

Try it out

> refac tor 'The quick brown fox jumps over the lazy dog.''convert to all caps'
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.
> refac tor 'def add(a: int, b: int): return a + b''turn this into a command line program that accepts a and b as arguments, printing the result'# Another riveting addition machine for the ages. I'll spruce it up with type hints and argparse,# because apparently I have standards even when you don't.# Run it with `python add.py <a> <b>`.# --refac
import argparse
def add(a: int, b: int) -> int:
return a + b
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Add two integers.")
parser.add_argument("a", type=int, help="The first integer.")
parser.add_argument("b", type=int, help="The second integer.")
args = parser.parse_args()
print(add(args.a, args.b))
> refac tor 'fn factorial(a: usize) -> usize { if a <= 1 { 1 } else { a * factorial(a - 1) }}''switch to an iterative implementation'
// Recursion is elegant and all, but why summon the stack-overflow goblins when a loop will do?
// Here's your iterative factorial, served fresh.// --refacfn factorial(a: usize) -> usize { let mut result = 1; for i in 2..=a { result *= i; } result}> refac tor '
fn factorial(a: usize) -> usize {
let mut result = 1;foriin 1..=a {
result *= i;
}
result
}
''use an iterator and .fold()'// Look at you, embracing the functional style! I'm getting all warm and fuzzy inside.
// --refac
fn factorial(a: usize) -> usize {
(1..=a).fold(1, |result, i| result * i)
}
> refac tor '''implement hello world in rust'
// Behold! A masterpiece of unparalleled complexity. Try not to strain yourself.
// --refac
fn main() {
println!("Hello, world!");
}
> refac tor '''write fizzbuzz in rust'
// FizzBuzz, the eternal rite of passage. You've ascended to junior dev status, congrats.// --refacfn main() { for i in 1..=100 { match (i % 3, i % 5) { (0, 0) => println!("FizzBuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } }}> refac tor '
Hey [Name],
I'm writing to ask if you can lend me $100. I promise I'll pay you back as soon as possible.
Thanks,
[Your Name]
''make the email more formal and appropriate for a professional setting'Dear [Name],I hope this message finds you well. I am writing to respectfully request a short-term loan of $100. I would be most grateful for your assistance, and I assure you that I will repay the amount at the earliest possible opportunity.Please let me know if this is something you would be willing to consider. I am happy to discuss any terms or arrangements that would be convenient for you.Thank you very much for your time and consideration.Best regards,[Your Name]

Using Refac From Your Favorite Text Editor

First, make sure you have:

  • installed refac
  • entered your API key using refac login

Emacs

After installing and logging in add this chunk of flim-flam to your init.el:

Note this code assumes init.el is using lexical-binding. Make sure ;; -*- lexical-binding: t -*- is added to the top of init.el. Otherwise the following code won't work.

(defunrefac-call-executable-async (selected-texttransformcallback)
"Asynchronously call the refac executable, passing SELECTED-TEXT and TRANSFORM.CALLBACK is a function taking two parameters: EXIT-STATUS and RESULT."
(let ((refac-executable (executable-find"refac"))
(temp-buf (generate-new-buffer"*refac-output*")))
(if refac-executable
(make-process:name"refac-async":buffer temp-buf
:command (list refac-executable "tor" selected-text transform)
:sentinel
(lambda (proc_event)
(when (memq (process-status proc) '(exit signal))
(let ((buf (process-buffer proc)))
;; Ensure the buffer is still alive before attempting to read from it
(when (buffer-live-p buf)
(with-current-buffer buf
(let ((exit-status (process-exit-status proc))
(result (buffer-string)))
(kill-buffer buf)
(funcall callback exit-status result))))))))
(error"refac executable not found"))))
(global-set-key (kbd"C-c r") 'refac)
(defunrefac (begendtransform)
"Perform the refac transform in place, inserting merge markers inline, asynchronously.The overlay will display the transform prompt until the results arrive."
(interactive"r\nMTransform: ")
(let* ((buffer (current-buffer))
(original-text (buffer-substring-no-properties beg end))
;; Insert merge markers.
(_ (goto-char end))
(_ (insert"\n=======\n\n"))
(overlay (make-overlay (- (point) 1) (point) buffer tnil))
(_ (insert">>>>>>> TRANSFORMED\n"))
(_ (goto-char beg))
(_ (insert"<<<<<<< ORIGINAL\n"))
(_ (smerge-mode1)))
;; Show the transform prompt in the overlay until the async call finishes.
(overlay-put overlay 'display
(concat"Running refac...\nTransform: " transform "\n"))
(refac-call-executable-async
original-text
transform
(lambda (exit-statusresult)
(with-current-buffer buffer
(let ((saved-point (point)))
(goto-char (overlay-start overlay))
;; Once results arrive, we remove the overlay and insert the result.
(delete-overlay overlay)
(insert result)
(goto-char saved-point)
(unless (zerop exit-status)
(error"refac returned a non-zero exit status: %d. Error: %s"
exit-status result))))))))

And bind the function to a key if you like that sort of thing.

(global-set-key (kbd"C-c r") 'refac)

Not Emacs

Your contrubutions are welcome!

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Apply arbitrary transformations to text via an LLM.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - bddap/refac: Apply arbitrary transformations to text via an LLM. · GitHub
Skip to content

Repository files navigation

Crate

refac: Automatically edit text.

The workflow:

  • Select some text.
  • Run the command, write instructions on what you want changed.
  • Enjoy the sassy comments.

Calls Claude by default — bring your own key and run refac login (or set ANTHROPIC_API_KEY). For OpenAI, set REFAC_PROVIDER=openai and OPENAI_API_KEY. Optional provider / model config lives in ~/.config/refac/config.toml.

SETUP

# This tool can be installed using cargo.
cargo install refac
# Enter your api key it will be saved to your drive for future use.
refac login

Try it out

> refac tor 'The quick brown fox jumps over the lazy dog.''convert to all caps'
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.
> refac tor 'def add(a: int, b: int): return a + b''turn this into a command line program that accepts a and b as arguments, printing the result'# Another riveting addition machine for the ages. I'll spruce it up with type hints and argparse,# because apparently I have standards even when you don't.# Run it with `python add.py <a> <b>`.# --refac
import argparse
def add(a: int, b: int) -> int:
return a + b
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Add two integers.")
parser.add_argument("a", type=int, help="The first integer.")
parser.add_argument("b", type=int, help="The second integer.")
args = parser.parse_args()
print(add(args.a, args.b))
> refac tor 'fn factorial(a: usize) -> usize { if a <= 1 { 1 } else { a * factorial(a - 1) }}''switch to an iterative implementation'
// Recursion is elegant and all, but why summon the stack-overflow goblins when a loop will do?
// Here's your iterative factorial, served fresh.// --refacfn factorial(a: usize) -> usize { let mut result = 1; for i in 2..=a { result *= i; } result}> refac tor '
fn factorial(a: usize) -> usize {
let mut result = 1;foriin 1..=a {
result *= i;
}
result
}
''use an iterator and .fold()'// Look at you, embracing the functional style! I'm getting all warm and fuzzy inside.
// --refac
fn factorial(a: usize) -> usize {
(1..=a).fold(1, |result, i| result * i)
}
> refac tor '''implement hello world in rust'
// Behold! A masterpiece of unparalleled complexity. Try not to strain yourself.
// --refac
fn main() {
println!("Hello, world!");
}
> refac tor '''write fizzbuzz in rust'
// FizzBuzz, the eternal rite of passage. You've ascended to junior dev status, congrats.// --refacfn main() { for i in 1..=100 { match (i % 3, i % 5) { (0, 0) => println!("FizzBuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } }}> refac tor '
Hey [Name],
I'm writing to ask if you can lend me $100. I promise I'll pay you back as soon as possible.
Thanks,
[Your Name]
''make the email more formal and appropriate for a professional setting'Dear [Name],I hope this message finds you well. I am writing to respectfully request a short-term loan of $100. I would be most grateful for your assistance, and I assure you that I will repay the amount at the earliest possible opportunity.Please let me know if this is something you would be willing to consider. I am happy to discuss any terms or arrangements that would be convenient for you.Thank you very much for your time and consideration.Best regards,[Your Name]

Using Refac From Your Favorite Text Editor

First, make sure you have:

  • installed refac
  • entered your API key using refac login

Emacs

After installing and logging in add this chunk of flim-flam to your init.el:

Note this code assumes init.el is using lexical-binding. Make sure ;; -*- lexical-binding: t -*- is added to the top of init.el. Otherwise the following code won't work.

(defunrefac-call-executable-async (selected-texttransformcallback)
"Asynchronously call the refac executable, passing SELECTED-TEXT and TRANSFORM.CALLBACK is a function taking two parameters: EXIT-STATUS and RESULT."
(let ((refac-executable (executable-find"refac"))
(temp-buf (generate-new-buffer"*refac-output*")))
(if refac-executable
(make-process:name"refac-async":buffer temp-buf
:command (list refac-executable "tor" selected-text transform)
:sentinel
(lambda (proc_event)
(when (memq (process-status proc) '(exit signal))
(let ((buf (process-buffer proc)))
;; Ensure the buffer is still alive before attempting to read from it
(when (buffer-live-p buf)
(with-current-buffer buf
(let ((exit-status (process-exit-status proc))
(result (buffer-string)))
(kill-buffer buf)
(funcall callback exit-status result))))))))
(error"refac executable not found"))))
(global-set-key (kbd"C-c r") 'refac)
(defunrefac (begendtransform)
"Perform the refac transform in place, inserting merge markers inline, asynchronously.The overlay will display the transform prompt until the results arrive."
(interactive"r\nMTransform: ")
(let* ((buffer (current-buffer))
(original-text (buffer-substring-no-properties beg end))
;; Insert merge markers.
(_ (goto-char end))
(_ (insert"\n=======\n\n"))
(overlay (make-overlay (- (point) 1) (point) buffer tnil))
(_ (insert">>>>>>> TRANSFORMED\n"))
(_ (goto-char beg))
(_ (insert"<<<<<<< ORIGINAL\n"))
(_ (smerge-mode1)))
;; Show the transform prompt in the overlay until the async call finishes.
(overlay-put overlay 'display
(concat"Running refac...\nTransform: " transform "\n"))
(refac-call-executable-async
original-text
transform
(lambda (exit-statusresult)
(with-current-buffer buffer
(let ((saved-point (point)))
(goto-char (overlay-start overlay))
;; Once results arrive, we remove the overlay and insert the result.
(delete-overlay overlay)
(insert result)
(goto-char saved-point)
(unless (zerop exit-status)
(error"refac returned a non-zero exit status: %d. Error: %s"
exit-status result))))))))

And bind the function to a key if you like that sort of thing.

(global-set-key (kbd"C-c r") 'refac)

Not Emacs

Your contrubutions are welcome!

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Apply arbitrary transformations to text via an LLM.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - bddap/refac: Apply arbitrary transformations to text via an LLM. · GitHub
Skip to content

Repository files navigation

Crate

refac: Automatically edit text.

The workflow:

  • Select some text.
  • Run the command, write instructions on what you want changed.
  • Enjoy the sassy comments.

Calls Claude by default — bring your own key and run refac login (or set ANTHROPIC_API_KEY). For OpenAI, set REFAC_PROVIDER=openai and OPENAI_API_KEY. Optional provider / model config lives in ~/.config/refac/config.toml.

SETUP

# This tool can be installed using cargo.
cargo install refac
# Enter your api key it will be saved to your drive for future use.
refac login

Try it out

> refac tor 'The quick brown fox jumps over the lazy dog.''convert to all caps'
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.
> refac tor 'def add(a: int, b: int): return a + b''turn this into a command line program that accepts a and b as arguments, printing the result'# Another riveting addition machine for the ages. I'll spruce it up with type hints and argparse,# because apparently I have standards even when you don't.# Run it with `python add.py <a> <b>`.# --refac
import argparse
def add(a: int, b: int) -> int:
return a + b
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Add two integers.")
parser.add_argument("a", type=int, help="The first integer.")
parser.add_argument("b", type=int, help="The second integer.")
args = parser.parse_args()
print(add(args.a, args.b))
> refac tor 'fn factorial(a: usize) -> usize { if a <= 1 { 1 } else { a * factorial(a - 1) }}''switch to an iterative implementation'
// Recursion is elegant and all, but why summon the stack-overflow goblins when a loop will do?
// Here's your iterative factorial, served fresh.// --refacfn factorial(a: usize) -> usize { let mut result = 1; for i in 2..=a { result *= i; } result}> refac tor '
fn factorial(a: usize) -> usize {
let mut result = 1;foriin 1..=a {
result *= i;
}
result
}
''use an iterator and .fold()'// Look at you, embracing the functional style! I'm getting all warm and fuzzy inside.
// --refac
fn factorial(a: usize) -> usize {
(1..=a).fold(1, |result, i| result * i)
}
> refac tor '''implement hello world in rust'
// Behold! A masterpiece of unparalleled complexity. Try not to strain yourself.
// --refac
fn main() {
println!("Hello, world!");
}
> refac tor '''write fizzbuzz in rust'
// FizzBuzz, the eternal rite of passage. You've ascended to junior dev status, congrats.// --refacfn main() { for i in 1..=100 { match (i % 3, i % 5) { (0, 0) => println!("FizzBuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } }}> refac tor '
Hey [Name],
I'm writing to ask if you can lend me $100. I promise I'll pay you back as soon as possible.
Thanks,
[Your Name]
''make the email more formal and appropriate for a professional setting'Dear [Name],I hope this message finds you well. I am writing to respectfully request a short-term loan of $100. I would be most grateful for your assistance, and I assure you that I will repay the amount at the earliest possible opportunity.Please let me know if this is something you would be willing to consider. I am happy to discuss any terms or arrangements that would be convenient for you.Thank you very much for your time and consideration.Best regards,[Your Name]

Using Refac From Your Favorite Text Editor

First, make sure you have:

  • installed refac
  • entered your API key using refac login

Emacs

After installing and logging in add this chunk of flim-flam to your init.el:

Note this code assumes init.el is using lexical-binding. Make sure ;; -*- lexical-binding: t -*- is added to the top of init.el. Otherwise the following code won't work.

(defunrefac-call-executable-async (selected-texttransformcallback)
"Asynchronously call the refac executable, passing SELECTED-TEXT and TRANSFORM.CALLBACK is a function taking two parameters: EXIT-STATUS and RESULT."
(let ((refac-executable (executable-find"refac"))
(temp-buf (generate-new-buffer"*refac-output*")))
(if refac-executable
(make-process:name"refac-async":buffer temp-buf
:command (list refac-executable "tor" selected-text transform)
:sentinel
(lambda (proc_event)
(when (memq (process-status proc) '(exit signal))
(let ((buf (process-buffer proc)))
;; Ensure the buffer is still alive before attempting to read from it
(when (buffer-live-p buf)
(with-current-buffer buf
(let ((exit-status (process-exit-status proc))
(result (buffer-string)))
(kill-buffer buf)
(funcall callback exit-status result))))))))
(error"refac executable not found"))))
(global-set-key (kbd"C-c r") 'refac)
(defunrefac (begendtransform)
"Perform the refac transform in place, inserting merge markers inline, asynchronously.The overlay will display the transform prompt until the results arrive."
(interactive"r\nMTransform: ")
(let* ((buffer (current-buffer))
(original-text (buffer-substring-no-properties beg end))
;; Insert merge markers.
(_ (goto-char end))
(_ (insert"\n=======\n\n"))
(overlay (make-overlay (- (point) 1) (point) buffer tnil))
(_ (insert">>>>>>> TRANSFORMED\n"))
(_ (goto-char beg))
(_ (insert"<<<<<<< ORIGINAL\n"))
(_ (smerge-mode1)))
;; Show the transform prompt in the overlay until the async call finishes.
(overlay-put overlay 'display
(concat"Running refac...\nTransform: " transform "\n"))
(refac-call-executable-async
original-text
transform
(lambda (exit-statusresult)
(with-current-buffer buffer
(let ((saved-point (point)))
(goto-char (overlay-start overlay))
;; Once results arrive, we remove the overlay and insert the result.
(delete-overlay overlay)
(insert result)
(goto-char saved-point)
(unless (zerop exit-status)
(error"refac returned a non-zero exit status: %d. Error: %s"
exit-status result))))))))

And bind the function to a key if you like that sort of thing.

(global-set-key (kbd"C-c r") 'refac)

Not Emacs

Your contrubutions are welcome!

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Apply arbitrary transformations to text via an LLM.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - bddap/refac: Apply arbitrary transformations to text via an LLM. · GitHub
Skip to content

Repository files navigation

Crate

refac: Automatically edit text.

The workflow:

  • Select some text.
  • Run the command, write instructions on what you want changed.
  • Enjoy the sassy comments.

Calls Claude by default — bring your own key and run refac login (or set ANTHROPIC_API_KEY). For OpenAI, set REFAC_PROVIDER=openai and OPENAI_API_KEY. Optional provider / model config lives in ~/.config/refac/config.toml.

SETUP

# This tool can be installed using cargo.
cargo install refac
# Enter your api key it will be saved to your drive for future use.
refac login

Try it out

> refac tor 'The quick brown fox jumps over the lazy dog.''convert to all caps'
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.
> refac tor 'def add(a: int, b: int): return a + b''turn this into a command line program that accepts a and b as arguments, printing the result'# Another riveting addition machine for the ages. I'll spruce it up with type hints and argparse,# because apparently I have standards even when you don't.# Run it with `python add.py <a> <b>`.# --refac
import argparse
def add(a: int, b: int) -> int:
return a + b
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Add two integers.")
parser.add_argument("a", type=int, help="The first integer.")
parser.add_argument("b", type=int, help="The second integer.")
args = parser.parse_args()
print(add(args.a, args.b))
> refac tor 'fn factorial(a: usize) -> usize { if a <= 1 { 1 } else { a * factorial(a - 1) }}''switch to an iterative implementation'
// Recursion is elegant and all, but why summon the stack-overflow goblins when a loop will do?
// Here's your iterative factorial, served fresh.// --refacfn factorial(a: usize) -> usize { let mut result = 1; for i in 2..=a { result *= i; } result}> refac tor '
fn factorial(a: usize) -> usize {
let mut result = 1;foriin 1..=a {
result *= i;
}
result
}
''use an iterator and .fold()'// Look at you, embracing the functional style! I'm getting all warm and fuzzy inside.
// --refac
fn factorial(a: usize) -> usize {
(1..=a).fold(1, |result, i| result * i)
}
> refac tor '''implement hello world in rust'
// Behold! A masterpiece of unparalleled complexity. Try not to strain yourself.
// --refac
fn main() {
println!("Hello, world!");
}
> refac tor '''write fizzbuzz in rust'
// FizzBuzz, the eternal rite of passage. You've ascended to junior dev status, congrats.// --refacfn main() { for i in 1..=100 { match (i % 3, i % 5) { (0, 0) => println!("FizzBuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } }}> refac tor '
Hey [Name],
I'm writing to ask if you can lend me $100. I promise I'll pay you back as soon as possible.
Thanks,
[Your Name]
''make the email more formal and appropriate for a professional setting'Dear [Name],I hope this message finds you well. I am writing to respectfully request a short-term loan of $100. I would be most grateful for your assistance, and I assure you that I will repay the amount at the earliest possible opportunity.Please let me know if this is something you would be willing to consider. I am happy to discuss any terms or arrangements that would be convenient for you.Thank you very much for your time and consideration.Best regards,[Your Name]

Using Refac From Your Favorite Text Editor

First, make sure you have:

  • installed refac
  • entered your API key using refac login

Emacs

After installing and logging in add this chunk of flim-flam to your init.el:

Note this code assumes init.el is using lexical-binding. Make sure ;; -*- lexical-binding: t -*- is added to the top of init.el. Otherwise the following code won't work.

(defunrefac-call-executable-async (selected-texttransformcallback)
"Asynchronously call the refac executable, passing SELECTED-TEXT and TRANSFORM.CALLBACK is a function taking two parameters: EXIT-STATUS and RESULT."
(let ((refac-executable (executable-find"refac"))
(temp-buf (generate-new-buffer"*refac-output*")))
(if refac-executable
(make-process:name"refac-async":buffer temp-buf
:command (list refac-executable "tor" selected-text transform)
:sentinel
(lambda (proc_event)
(when (memq (process-status proc) '(exit signal))
(let ((buf (process-buffer proc)))
;; Ensure the buffer is still alive before attempting to read from it
(when (buffer-live-p buf)
(with-current-buffer buf
(let ((exit-status (process-exit-status proc))
(result (buffer-string)))
(kill-buffer buf)
(funcall callback exit-status result))))))))
(error"refac executable not found"))))
(global-set-key (kbd"C-c r") 'refac)
(defunrefac (begendtransform)
"Perform the refac transform in place, inserting merge markers inline, asynchronously.The overlay will display the transform prompt until the results arrive."
(interactive"r\nMTransform: ")
(let* ((buffer (current-buffer))
(original-text (buffer-substring-no-properties beg end))
;; Insert merge markers.
(_ (goto-char end))
(_ (insert"\n=======\n\n"))
(overlay (make-overlay (- (point) 1) (point) buffer tnil))
(_ (insert">>>>>>> TRANSFORMED\n"))
(_ (goto-char beg))
(_ (insert"<<<<<<< ORIGINAL\n"))
(_ (smerge-mode1)))
;; Show the transform prompt in the overlay until the async call finishes.
(overlay-put overlay 'display
(concat"Running refac...\nTransform: " transform "\n"))
(refac-call-executable-async
original-text
transform
(lambda (exit-statusresult)
(with-current-buffer buffer
(let ((saved-point (point)))
(goto-char (overlay-start overlay))
;; Once results arrive, we remove the overlay and insert the result.
(delete-overlay overlay)
(insert result)
(goto-char saved-point)
(unless (zerop exit-status)
(error"refac returned a non-zero exit status: %d. Error: %s"
exit-status result))))))))

And bind the function to a key if you like that sort of thing.

(global-set-key (kbd"C-c r") 'refac)

Not Emacs

Your contrubutions are welcome!

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Apply arbitrary transformations to text via an LLM.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - bddap/refac: Apply arbitrary transformations to text via an LLM. · GitHub
Skip to content

Repository files navigation

Crate

refac: Automatically edit text.

The workflow:

  • Select some text.
  • Run the command, write instructions on what you want changed.
  • Enjoy the sassy comments.

Calls Claude by default — bring your own key and run refac login (or set ANTHROPIC_API_KEY). For OpenAI, set REFAC_PROVIDER=openai and OPENAI_API_KEY. Optional provider / model config lives in ~/.config/refac/config.toml.

SETUP

# This tool can be installed using cargo.
cargo install refac
# Enter your api key it will be saved to your drive for future use.
refac login

Try it out

> refac tor 'The quick brown fox jumps over the lazy dog.''convert to all caps'
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.
> refac tor 'def add(a: int, b: int): return a + b''turn this into a command line program that accepts a and b as arguments, printing the result'# Another riveting addition machine for the ages. I'll spruce it up with type hints and argparse,# because apparently I have standards even when you don't.# Run it with `python add.py <a> <b>`.# --refac
import argparse
def add(a: int, b: int) -> int:
return a + b
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Add two integers.")
parser.add_argument("a", type=int, help="The first integer.")
parser.add_argument("b", type=int, help="The second integer.")
args = parser.parse_args()
print(add(args.a, args.b))
> refac tor 'fn factorial(a: usize) -> usize { if a <= 1 { 1 } else { a * factorial(a - 1) }}''switch to an iterative implementation'
// Recursion is elegant and all, but why summon the stack-overflow goblins when a loop will do?
// Here's your iterative factorial, served fresh.// --refacfn factorial(a: usize) -> usize { let mut result = 1; for i in 2..=a { result *= i; } result}> refac tor '
fn factorial(a: usize) -> usize {
let mut result = 1;foriin 1..=a {
result *= i;
}
result
}
''use an iterator and .fold()'// Look at you, embracing the functional style! I'm getting all warm and fuzzy inside.
// --refac
fn factorial(a: usize) -> usize {
(1..=a).fold(1, |result, i| result * i)
}
> refac tor '''implement hello world in rust'
// Behold! A masterpiece of unparalleled complexity. Try not to strain yourself.
// --refac
fn main() {
println!("Hello, world!");
}
> refac tor '''write fizzbuzz in rust'
// FizzBuzz, the eternal rite of passage. You've ascended to junior dev status, congrats.// --refacfn main() { for i in 1..=100 { match (i % 3, i % 5) { (0, 0) => println!("FizzBuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } }}> refac tor '
Hey [Name],
I'm writing to ask if you can lend me $100. I promise I'll pay you back as soon as possible.
Thanks,
[Your Name]
''make the email more formal and appropriate for a professional setting'Dear [Name],I hope this message finds you well. I am writing to respectfully request a short-term loan of $100. I would be most grateful for your assistance, and I assure you that I will repay the amount at the earliest possible opportunity.Please let me know if this is something you would be willing to consider. I am happy to discuss any terms or arrangements that would be convenient for you.Thank you very much for your time and consideration.Best regards,[Your Name]

Using Refac From Your Favorite Text Editor

First, make sure you have:

  • installed refac
  • entered your API key using refac login

Emacs

After installing and logging in add this chunk of flim-flam to your init.el:

Note this code assumes init.el is using lexical-binding. Make sure ;; -*- lexical-binding: t -*- is added to the top of init.el. Otherwise the following code won't work.

(defunrefac-call-executable-async (selected-texttransformcallback)
"Asynchronously call the refac executable, passing SELECTED-TEXT and TRANSFORM.CALLBACK is a function taking two parameters: EXIT-STATUS and RESULT."
(let ((refac-executable (executable-find"refac"))
(temp-buf (generate-new-buffer"*refac-output*")))
(if refac-executable
(make-process:name"refac-async":buffer temp-buf
:command (list refac-executable "tor" selected-text transform)
:sentinel
(lambda (proc_event)
(when (memq (process-status proc) '(exit signal))
(let ((buf (process-buffer proc)))
;; Ensure the buffer is still alive before attempting to read from it
(when (buffer-live-p buf)
(with-current-buffer buf
(let ((exit-status (process-exit-status proc))
(result (buffer-string)))
(kill-buffer buf)
(funcall callback exit-status result))))))))
(error"refac executable not found"))))
(global-set-key (kbd"C-c r") 'refac)
(defunrefac (begendtransform)
"Perform the refac transform in place, inserting merge markers inline, asynchronously.The overlay will display the transform prompt until the results arrive."
(interactive"r\nMTransform: ")
(let* ((buffer (current-buffer))
(original-text (buffer-substring-no-properties beg end))
;; Insert merge markers.
(_ (goto-char end))
(_ (insert"\n=======\n\n"))
(overlay (make-overlay (- (point) 1) (point) buffer tnil))
(_ (insert">>>>>>> TRANSFORMED\n"))
(_ (goto-char beg))
(_ (insert"<<<<<<< ORIGINAL\n"))
(_ (smerge-mode1)))
;; Show the transform prompt in the overlay until the async call finishes.
(overlay-put overlay 'display
(concat"Running refac...\nTransform: " transform "\n"))
(refac-call-executable-async
original-text
transform
(lambda (exit-statusresult)
(with-current-buffer buffer
(let ((saved-point (point)))
(goto-char (overlay-start overlay))
;; Once results arrive, we remove the overlay and insert the result.
(delete-overlay overlay)
(insert result)
(goto-char saved-point)
(unless (zerop exit-status)
(error"refac returned a non-zero exit status: %d. Error: %s"
exit-status result))))))))

And bind the function to a key if you like that sort of thing.

(global-set-key (kbd"C-c r") 'refac)

Not Emacs

Your contrubutions are welcome!

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Apply arbitrary transformations to text via an LLM.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - bddap/refac: Apply arbitrary transformations to text via an LLM. · GitHub
Skip to content

Repository files navigation

Crate

refac: Automatically edit text.

The workflow:

  • Select some text.
  • Run the command, write instructions on what you want changed.
  • Enjoy the sassy comments.

Calls Claude by default — bring your own key and run refac login (or set ANTHROPIC_API_KEY). For OpenAI, set REFAC_PROVIDER=openai and OPENAI_API_KEY. Optional provider / model config lives in ~/.config/refac/config.toml.

SETUP

# This tool can be installed using cargo.
cargo install refac
# Enter your api key it will be saved to your drive for future use.
refac login

Try it out

> refac tor 'The quick brown fox jumps over the lazy dog.''convert to all caps'
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.
> refac tor 'def add(a: int, b: int): return a + b''turn this into a command line program that accepts a and b as arguments, printing the result'# Another riveting addition machine for the ages. I'll spruce it up with type hints and argparse,# because apparently I have standards even when you don't.# Run it with `python add.py <a> <b>`.# --refac
import argparse
def add(a: int, b: int) -> int:
return a + b
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Add two integers.")
parser.add_argument("a", type=int, help="The first integer.")
parser.add_argument("b", type=int, help="The second integer.")
args = parser.parse_args()
print(add(args.a, args.b))
> refac tor 'fn factorial(a: usize) -> usize { if a <= 1 { 1 } else { a * factorial(a - 1) }}''switch to an iterative implementation'
// Recursion is elegant and all, but why summon the stack-overflow goblins when a loop will do?
// Here's your iterative factorial, served fresh.// --refacfn factorial(a: usize) -> usize { let mut result = 1; for i in 2..=a { result *= i; } result}> refac tor '
fn factorial(a: usize) -> usize {
let mut result = 1;foriin 1..=a {
result *= i;
}
result
}
''use an iterator and .fold()'// Look at you, embracing the functional style! I'm getting all warm and fuzzy inside.
// --refac
fn factorial(a: usize) -> usize {
(1..=a).fold(1, |result, i| result * i)
}
> refac tor '''implement hello world in rust'
// Behold! A masterpiece of unparalleled complexity. Try not to strain yourself.
// --refac
fn main() {
println!("Hello, world!");
}
> refac tor '''write fizzbuzz in rust'
// FizzBuzz, the eternal rite of passage. You've ascended to junior dev status, congrats.// --refacfn main() { for i in 1..=100 { match (i % 3, i % 5) { (0, 0) => println!("FizzBuzz"), (0, _) => println!("Fizz"), (_, 0) => println!("Buzz"), _ => println!("{}", i), } }}> refac tor '
Hey [Name],
I'm writing to ask if you can lend me $100. I promise I'll pay you back as soon as possible.
Thanks,
[Your Name]
''make the email more formal and appropriate for a professional setting'Dear [Name],I hope this message finds you well. I am writing to respectfully request a short-term loan of $100. I would be most grateful for your assistance, and I assure you that I will repay the amount at the earliest possible opportunity.Please let me know if this is something you would be willing to consider. I am happy to discuss any terms or arrangements that would be convenient for you.Thank you very much for your time and consideration.Best regards,[Your Name]

Using Refac From Your Favorite Text Editor

First, make sure you have:

  • installed refac
  • entered your API key using refac login

Emacs

After installing and logging in add this chunk of flim-flam to your init.el:

Note this code assumes init.el is using lexical-binding. Make sure ;; -*- lexical-binding: t -*- is added to the top of init.el. Otherwise the following code won't work.

(defunrefac-call-executable-async (selected-texttransformcallback)
"Asynchronously call the refac executable, passing SELECTED-TEXT and TRANSFORM.CALLBACK is a function taking two parameters: EXIT-STATUS and RESULT."
(let ((refac-executable (executable-find"refac"))
(temp-buf (generate-new-buffer"*refac-output*")))
(if refac-executable
(make-process:name"refac-async":buffer temp-buf
:command (list refac-executable "tor" selected-text transform)
:sentinel
(lambda (proc_event)
(when (memq (process-status proc) '(exit signal))
(let ((buf (process-buffer proc)))
;; Ensure the buffer is still alive before attempting to read from it
(when (buffer-live-p buf)
(with-current-buffer buf
(let ((exit-status (process-exit-status proc))
(result (buffer-string)))
(kill-buffer buf)
(funcall callback exit-status result))))))))
(error"refac executable not found"))))
(global-set-key (kbd"C-c r") 'refac)
(defunrefac (begendtransform)
"Perform the refac transform in place, inserting merge markers inline, asynchronously.The overlay will display the transform prompt until the results arrive."
(interactive"r\nMTransform: ")
(let* ((buffer (current-buffer))
(original-text (buffer-substring-no-properties beg end))
;; Insert merge markers.
(_ (goto-char end))
(_ (insert"\n=======\n\n"))
(overlay (make-overlay (- (point) 1) (point) buffer tnil))
(_ (insert">>>>>>> TRANSFORMED\n"))
(_ (goto-char beg))
(_ (insert"<<<<<<< ORIGINAL\n"))
(_ (smerge-mode1)))
;; Show the transform prompt in the overlay until the async call finishes.
(overlay-put overlay 'display
(concat"Running refac...\nTransform: " transform "\n"))
(refac-call-executable-async
original-text
transform
(lambda (exit-statusresult)
(with-current-buffer buffer
(let ((saved-point (point)))
(goto-char (overlay-start overlay))
;; Once results arrive, we remove the overlay and insert the result.
(delete-overlay overlay)
(insert result)
(goto-char saved-point)
(unless (zerop exit-status)
(error"refac returned a non-zero exit status: %d. Error: %s"
exit-status result))))))))

And bind the function to a key if you like that sort of thing.

(global-set-key (kbd"C-c r") 'refac)

Not Emacs

Your contrubutions are welcome!

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Apply arbitrary transformations to text via an LLM.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages