Code Monkey home page Code Monkey logo

isend-mode.el's Introduction

isend-mode MELPA

isend-mode is an Emacs extension allowing interaction with code interpreters in ansi-term/term or vterm buffers. Some language-specific modes (e.g. python.el) already provide similar features; isend-mode does the same in a language-agnostic way.

screencast

Installation

From MELPA

The easiest (and recommended) way to get up and running with isend-mode is to install it through MELPA. If you're not already using MELPA, it's quite easy to setup.

From sources

Just clone the repository. For example:

git clone https://github.com/ffevotte/isend-mode.el.git /path/to/isend-mode

Then, add the following lines in your Emacs initialization file (.emacs or .emacs.d/init.el):

(add-to-list 'load-path "/path/to/isend-mode")
(require 'isend-mode)

Usage

Getting started

The following example demonstrates using isend-mode to interact with a shell in an ansi-term buffer. Please note that any other interpreter could have been used (e.g. python, perl or anything else) and term would have worked as well.

  1. Open an ansi-term buffer where the interpeter will live. For example:

    M-x ansi-term RET /bin/sh RET

  2. Open a buffer with the code you want to execute, and associate it to the interpreter buffer using the isend-associate command (or isend, which is a shorter alias). For example:

    M-x isend RET *ansi-term* RET

  3. Hitting C-RET will send the current line to the interpreter. If a region is active, all lines spanned by the region will be sent (i.e. no line will be only partially sent). Point is then moved to the next non-empty line (but see configuration variable isend-skip-empty-lines).

Use cases

  • Interactive demo of a text-based program: you prepare all the commands you want to run in a buffer and interactively send them to the interpreter as if you had typed them.

  • Running interpreted code step by step: this is for example useful if you often run the same list of shell commands but don't want to formally handle all possible errors in a script.

Advanced usage

Apart from isend-send, bound by default to C-RET and described above, isend-mode defines a few other commands that you are free to use interactively and bind to custom keys:

  • isend-send-buffer: sends the whole buffer. This is functionnally equivalent to calling mark-whole-buffer (C-xh), then isend-send.

  • isend-send-defun: sends the current defun. See the configuration variable isend-mark-defun-function for how to mark a function definition.

  • isend-display-buffer: display the buffer associated to the current one.

Customization

isend-mode can be customized with M-x customize-group RET isend RET

The variables which can be set to customize isend's behaviour are:

  • isend-forward-line: if non-nil (default), isend advances to the next line after having sent some content using C-RET.

  • isend-skip-empty-lines: if non-nil (default), isend will skip empty lines (i.e. lines containing only whitespace) and position point on the first following non-empty line. Some interpreters (like Python) care about empty lines. In such cases it might be useful to set isend-skip-empty-lines to nil.

  • isend-strip-empty-lines: if non-nil, isend will remove empty (or whitespace-only) lines from the region before sending it to the interpreter. Note that this only works when sending an entire region (as opposed to a single line).

  • isend-delete-indentation: if non-nil, isend will delete indentation from all lines in the region. Note that this only works when sending a region (as opposed to a single line). Relative indentation w.r.t the first line is preserved. This is useful e.g. to send Python blocks outside of their original context.

  • isend-end-with-empty-line: if non-nil, isend appends an empty line to regions sent. Note that this only works when sending an entire region (as opposed to a single line).

  • isend-bracketed-paste: if non-nil, isend uses bracketed paste. In short, this means it surrounds the contents it sends with escape sequences indicating the underlying process that this content is being pasted. Some interpreters (e.g. the Julia REPL) use this in meaningful ways.

  • isend-send-line-function and isend-send-region-function: if set, these are the functions called by isend to send a line or a region respectively. These functions are called in a buffer containing the text to be sent. They can modify it as needed before it is sent to the process. These functions also receive as argument the destination buffer, in case some interaction with it would be useful.

    Possible values include:

    • nil (default): do nothing (the contents will be sent as they are)
    • isend--ipython-paste: copy the contents to the clipoard, and send %paste to the interpreter buffer (where an iPython process is supposed to be running).
    • isend--ipython-cpaste: wrap the contents within a %cpaste command (an iPython processes is supposed to be running in the associated buffer).
  • isend-mark-defun: a function that will mark the current "defun" to be sent by isend-send-defun.

    Possible values include:

    • mark-defun (default): works for LISP-like languages
    • isend--python-mark-defun: marks the current top-level block in a python buffer

Setup helpers

A few helpers are provided to help setup isend when working with multiple languages:

;; If you work with shell scripts
(add-hook 'isend-mode-hook 'isend-default-shell-setup)

;; If you work with python scripts, one of those could be used (but not both!)
;;   - default python interpreter
(add-hook 'isend-mode-hook 'isend-default-python-setup)

;;   - specific setup for iPython
(add-hook 'isend-mode-hook 'isend-default-ipython-setup)

;; If you work with julia
(add-hook 'isend-mode-hook 'isend-default-julia-setup)

Contributing

If you make improvements to this code or have suggestions, please do not hesitate to fork the repository or submit bug reports on github. The repository's URL is:

https://github.com/ffevotte/isend-mode.el.git

Many thanks go to the following contributors:

License

Copyright (C) 2012-2019 François Févotte.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

isend-mode.el's People

Contributors

albertstartup avatar blade6570 avatar ffevotte avatar porterjamesj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

isend-mode.el's Issues

Navigating to the end of line (C-e) first will execute the following line (on C-RET)

Hi,

Say you have the following in foo.sh (with ansi-term as associated buffer):

cd
ls

If the point is before the 'c' or between 'c' and 'd', the cd command is executed on C-RET. But if the point is after 'd', for example when navigating to the end of the line with 'C-e' (or simply moving the point there with the arrow keys), then the ls command is executed. It would be great if there was an option to allow you to also execute the cd command in this case, which would also be how, for example, ESS (Emacs Speaks Statistics) works.

Thanks & cheers,
Marius

Interesting recommendation: a defadvice to have code be executed automatically?

I found this article which includes some recommended modifications to isend-mode.el.

Specifically it recommends defining advice for isend. Quoting literally:

But there is another annoying problem, isend only sends the code to a
specified buffer, but the code won’t be executed automatically.

With the following advice (with an advice you could run some commands before/after a specified function is invoked), after sending code, Emacs will switch to the destination buffer, execute the code that is sent and switch back to the original buffer.

1:  (defadvice isend-send (after advice-run-code-sent activate compile)
2:    "Execute whatever sent to the (Python) buffer"
3:    (interactive)
4:    (let ((old-buf (buffer-name)))
5:      (progn
6:        (switch-to-buffer isend--command-buffer)
7:        (goto-char (point-max))
8:        (comint-send-input)
9:        (switch-to-buffer old-buf))))

What do you think of this suggest this @ffevotte ? Is it really needed?

cpaste issue in ipython 5.1

After #9, everything works fine.
Although i use %paste, there seems to be some problems with cpaste.
First top level ipython input (i.e. not %cpaste input) doesn't understand "\n". That is fixed in the code below.
Second it is hard to deal with indent levels. I don't have a easy fix for that.
Feel free to close this issue, its just here for reference.

error with emacs 26.1: Symbol’s value as variable is void: term-last-input-start

Since commit 55244c3, isend doesn't work with emacs 26.1 anymore. M-x isend-send gives the following error:

isend-send: Symbol’s value as variable is void: term-last-input-start

Since this commit is a major rewrite (for emacs 27, it seems), is support for stable/previous emacs versions planned? Otherwise, you might consider setting the required emacs version in the package header.

Can't send blocks in selected region

I'm using isend in a Python buffer, with isend-default-python-setup, and it seems to be unable to deal with indentation when sending a region.

If I select a single line
1-2

it removes any of whitespace preceding it, in this case 8 spaces, and it works
2

If I select two lines instead
3

it complains that I'm sending multiple statements
4

And with more than 2 lines
5

gives a message regarding tabs and spaces, even though all of the indentation uses spaces.
6

How to skip comment lines?

I use the variable isend-skip-empty-lines, which makes walking through long scripts easy. I would also like to skip comment lines (# in bash). Is there something like isend-skip-comment-lines?

Working with IPython

Note: This issue is a follow up on this StackOverflow thread

@ffevotte You mentioned there is a way of sending %paste commands to an IPython session (which would effectively make the IPython interpreter run the most recent item in the kill ring) . I think you said there is a hook we can use for this, but I could not find the info on the documentation. Would you mind elaborating more on this? Thanks!

For reference: I git cloned the repository and am working on the ipython branch and with the most recent commit as of today (Jan. 24, 2013):

commit 8bf12cfb81bb64977b682f47e4140e774bc000d1
Author: François Févotte <[email protected]>
Date:   Tue Dec 18 11:03:41 2012 +0100

    Prepared packaging with MELPA

'Move to next line' -> Making it optional

It would be great to modify isend-send() so that the last line of the function:

 ;; Move point to the next line
 (isend--next-line))

is optional depending on a boolean variable the user can set. I am trying to learn elisp but I am still unsure how to do this. Any thoughts?

Testing term-send-input with IPython 5

As I reported in this other issue #6 I am having problems getting isend to work with the latest IPython 5 terminal. I thought this would be a good opportunity for me to try contribute to this great package, since it has been a life saver since I started using it!

I have a relatively basic knowledge of Elisp, but I was able to follow most of the logic in isend-mode.el. I suspect part of the problem that I am having is coming from what's being sent to the terminal, since the IPython 5 interpreter works perfectly fine otherwise running within my ansi-term buffers.

The key seems to be these lines: https://github.com/ffevotte/isend-mode.el/blob/master/isend-mode.el#L278-L282 which read:

  (cond
    ;; Terminal buffer: specifically call `term-send-input'
    ;; to handle both the char and line modes of `ansi-term'.
    ((eq major-mode 'term-mode)
     (term-send-input))

What does (eq major-mode 'term-mode) do? Is it a comparison to make sure that it's a term-mode before we invoke term-send-input ?

How does term-send-input know what to send to what buffer? I know that it's wrapped up within two statements:

  • (with-temp-buffer ...
  • (with-current-buffer destination ... where destination holds the buffer we associate beforehand.

Also, how can I test interactively sending a simple string to a given buffer (called "ipy" in my case) where I have an IPython terminal running?

skip-empty-lines doesn't work

With isend-skip-empty-lines set to t, when I run C-RET on an empty line, it is still sent to the shell. I looked at the code to try and fix it myself, but I'm not familiar enough with elisp to completely understand what you're doing, so I figured I'd let you know it wasn't working (for me at least). This is on Cocoa emacs on OSX, version 24.2.1.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.