Last active
October 18, 2024 13:50
-
-
Save garaud/06b38554103aa7120337 to your computer and use it in GitHub Desktop.
Pipe to Emacs: Insert a result from an UNIX command into a new Emacs buffer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
# Author: Damien Garaud | |
# Date: 2014-2015 | |
# License: Simplified BSD | |
"""Allow you to pipe command results into an Emacs buffer. Suppose you have an | |
Emacs server since you launch 'emacsclient'. | |
Can be use such as: | |
> ls -l | pipe-to-emacs.py | |
> hg cat -r 42 filename.py | pipe-to-emacs.py | |
Copy/paste this code to your ~/bin, make it executable and/or create an alias | |
'pe'. | |
It's possible to apply a major-mode if you pass the optional arg such as: | |
> git show HEAD~4:script.py | pe python-mode | |
Note: this is a Python3 script. | |
""" | |
import os | |
import sys | |
import subprocess | |
EMACS = 'emacsclient' | |
OPTIONS = '-n' | |
EVAL = '--eval' | |
MAXLINE = 100 | |
def escape_filter(data): | |
"""Escape backslash. | |
""" | |
return data.replace('\\', r"\\") | |
def double_quote_filter(data): | |
"""Escape double quotes. | |
""" | |
return data.replace('"', '\\"') | |
def read_stdin(maxline=MAXLINE): | |
"""Read stdin and return the content for each `maxline` | |
""" | |
buf = '' | |
for count, line in enumerate(sys.stdin): | |
buf += double_quote_filter(escape_filter(line)) | |
if count % maxline == 0: | |
yield buf | |
buf = '' | |
yield buf | |
def emacs_eval(lisp): | |
"""Launch emacs with code to evaluate. | |
""" | |
cmd = [EMACS, OPTIONS, EVAL, lisp] | |
return subprocess.call(cmd, stdout=subprocess.DEVNULL) | |
def create_buffer(name='*piped*'): | |
elisp = '(pop-to-buffer (get-buffer-create "{}"))'.format(name) | |
return emacs_eval(elisp) | |
def insert_to_buffer(name, content): | |
elisp = ('(with-current-buffer "{0}" ' | |
'(goto-char (point-max)) (insert "{1}"))').format(name, content) | |
return emacs_eval(elisp) | |
def set_major_mode(name, mode): | |
elisp = '(with-current-buffer "{0}" ({1}))'.format(name, mode) | |
return emacs_eval(elisp) | |
def main(mode=None): | |
"""Loop on stding and insert content into an new emacs buffer every `maxline` | |
linex (50 by default). | |
""" | |
bufname = '*piped*' | |
create_buffer(bufname) | |
for content in read_stdin(): | |
insert_to_buffer(bufname, content) | |
if mode is not None: | |
set_major_mode(bufname, mode) | |
if __name__ == '__main__': | |
print("pipe to emacs") | |
args = sys.argv | |
# Suppose this is just the name of the Emacs major-mode to apply | |
if len(args) > 1: | |
main(args[1]) | |
else: | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment