Git Product home page Git Product logo

skerrick's Introduction

Skerrick

noun: skerrick
the smallest bit.
"there's not a skerrick of food in the house"

REPL-driven development for NodeJS

  • Programming in tiny increments - Apply patches to your running program without having to restart it
  • Tell me more!

Inspired by (check them out!):

  • SLIME: The Superior Lisp Interaction Mode for Emacs
  • CIDER: The Clojure(Script) Interactive Development Environment that Rocks!
  • Calva: integrated REPL powered environment for enjoyable and productive Clojure and ClojureScript development in Visual Studio Code

⚠️ DISCLAIMERS ⚠️

  • THIS PROJECT IS IN ALPHA STATE! I WOULD APPRECIATE IT IF YOU REPORT ANY BUGS/ISSUES YOU FIND. MAYBE EVEN CONTRIBUTE PATCHES/FIXES IF YOU HAVE THE TIME ;)
  • The code is currently very messy and not well-written. I just wanted to get a working prototype out of the door as quickly as I could. I will be improving the implementation over time. Feel free to give me suggestions if you have any!

VSCode

Documentation

Emacs

MELPA

Demos

Basic

Basic usage

Module support

Module support

Requirements

  • node/npm installed and accessible by Emacs

Installation

skerrick is in MELPA

Or, if you're using Quelpa:

(quelpa '(skerrick :repo "anonimitoraf/skerrick" :fetcher github))

;; Needs to be run on the very first install of skerrick. Or when you want to upgrade.
(unless (equal (shell-command-to-string "type skerrick") "skerrick not found\n")
  (skerrick-install-or-upgrade-server-binary))

;; Should be run in a JS buffer; it is buffer specific.
;; (skerrick-start-server)

;; Now main function, entry point is:
;; M-x skerrick-eval-region

It may also be helpful to provide a quick keyboard shortcut. E.g., C-x C-e evaluates ELisp, so let's mimic that for JS buffers:

;; Evaluate a region, if any is selected; otherwise evaluate the current line.
(bind-key
 "C-x C-e"  (lambda ()
              (interactive)
              (if (use-region-p)
                  (skerrick-eval-region)
                (beginning-of-line)
                (set-mark-command nil)
                (end-of-line)
                (skerrick-eval-region)
                (pop-mark)))
 'js-mode-map)

Configuration

Configuration Desc Default
skerrick-server-port Port to run the skerrick server on 4321
skerrick-result-overlay-face Face used to display evaluation results
skerrick-result-overlay-char-count-trunc Results with char count longer than this are truncated 120
skerrick-pop-result-buffer-for-stdout Show result buffer if stdout is non-empty t
skerrick-pop-result-buffer-for-stderr Show result buffer if stderr is non-empty t

Usage

Command Desc
skerrick-install-or-upgrade-server-binary Needs to be run on the very first install of skerrick. Or when you want to upgrade.
skerrick-start-server Starts the server. Note that your current buffer will be evaluated, so you probably want to run this command while being on your program's entry point file.
skerrick-stop-server Stops the server.
skerrick-eval-region Evaluates the selected region. Shows the eval result as an overlay. Stdout/stderr get written to the buffer *skerrick-stdout-stderr*.

Write a plug-in for your editor/IDE!

NPM

  • npm install -g skerrick - this installs the bin skerrick

    Invoked like so: skerrick PORT ENTRYPOINT_FULL_FILE_PATH

  • The REST protocol is as simple as it can be:

    • POST to /eval payloads of shape:
        {
          "modulePath": "/full/path/to/file/of/code/to/eval",
          "code": "const x = 42; console.log(x); x + x;"
        }
    • Response shape:
        {
          "result": "84",
          "stdout": "42",
          "stderr": ""
        }
  • 🚀 Tell me about your plug-in so I can add it to this README! 🚀

skerrick's People

Contributors

alhassy avatar anonimitoraf avatar deepsourcebot avatar syohex 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  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  avatar

skerrick's Issues

Re-evaluating `export default` doesn't update imports

function b(n) {
  return 'b';
}
export default b;

and

import deef from './temp-2';
deef() // 'b'

is fine, but then,

function c(n) {
  return 'c';
}
export default c;

and

import deef from './temp-2';
deef() // 'b'

which should've printed out c instead

Sporadic failure upon evaluating region

I made a scratch.js file whose contents are let a = "Hello" then I started the skerrick server and selected the entire contents and tried to evaluate the region, but received an error.

  • This happens sporadically ---sometimes when the buffer contains malformed JS.

Here is what my Messages buffer shows:

Started skerrick server on 4321
[error] request--callback: peculiar error
[error] request-default-error-callback: http://localhost:4321/eval parse-error

Aside: Maybe something from https://github.com/abicky/nodejs-repl.el can be integrated into this project.

Error while starting server: `Cannot find module ...`

Really cool project, I really wanted something like this for quite a while. But I'm having issues while starting it.

Here is an example setup:

$ npm i -g @nestjs/cli
$ nest new project-name

This gives you an working base NestJS project. Then I tried to run skerrick server, like this:

skerrick 4321 $(pwd)/src/main.ts

Here is the output I got:

Click to expand!
--- Port: 4321
--- Entry point /var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts
--- Eval imports? false
code transformed:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.NestFactory = exports.APP_PIPE = exports.APP_INTERCEPTOR = exports.APP_GUARD = exports.APP_FILTER = void 0;

const tslib_1 = require("tslib");
/*
 * Nest @core
 * Copyright(c) 2017 - 2021 Kamil Mysliwiec
 * https://nestjs.com
 * MIT Licensed
 */


registerValue("/private/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/node_modules/@nestjs/core/index.js", "tslib_1", tslib_1);

require("reflect-metadata");

tslib_1.__exportStar(require("./adapters"), exports);

tslib_1.__exportStar(require("./application-config"), exports);

var constants_1 = require("./constants");

registerValue("/private/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/node_modules/@nestjs/core/index.js", "constants_1", constants_1);
Object.defineProperty(exports, "APP_FILTER", {
  enumerable: true,
  get: function () {
    return constants_1.APP_FILTER;
  }
});
Object.defineProperty(exports, "APP_GUARD", {
  enumerable: true,
  get: function () {
    return constants_1.APP_GUARD;
  }
});
Object.defineProperty(exports, "APP_INTERCEPTOR", {
  enumerable: true,
  get: function () {
    return constants_1.APP_INTERCEPTOR;
  }
});
Object.defineProperty(exports, "APP_PIPE", {
  enumerable: true,
  get: function () {
    return constants_1.APP_PIPE;
  }
});

tslib_1.__exportStar(require("./discovery"), exports);

tslib_1.__exportStar(require("./exceptions"), exports);

tslib_1.__exportStar(require("./helpers"), exports);

tslib_1.__exportStar(require("./injector"), exports);

tslib_1.__exportStar(require("./metadata-scanner"), exports);

tslib_1.__exportStar(require("./middleware"), exports);

tslib_1.__exportStar(require("./nest-application"), exports);

tslib_1.__exportStar(require("./nest-application-context"), exports);

var nest_factory_1 = require("./nest-factory");

registerValue("/private/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/node_modules/@nestjs/core/index.js", "nest_factory_1", nest_factory_1);
Object.defineProperty(exports, "NestFactory", {
  enumerable: true,
  get: function () {
    return nest_factory_1.NestFactory;
  }
});

tslib_1.__exportStar(require("./router"), exports);

return tslib_1.__exportStar(require("./services"), exports);

all imports Map(0) {}
ns imports for scope {}
ns for scope {}
Failed to normalize import path:  Error: Cannot find module './app.module'
Require stack:
- /var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.resolve (node:internal/modules/cjs/helpers:108:19)
    at normalizeImportPath (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:443:20)
    at PluginPass.enter (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:404:47)
    at newFn (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/visitors.js:177:21)
    at NodePath._call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:53:20)
    at NodePath.call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:40:17)
    at NodePath.visit (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:100:31)
    at TraversalContext.visitQueue (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:103:16)
    at TraversalContext.visitMultiple (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:72:17) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts'
  ]
}
/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/core/lib/transformation/index.js:45
    throw e;
    ^

Error: Cannot find module './app.module'
Require stack:
- /var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.resolve (node:internal/modules/cjs/helpers:108:19)
    at normalizeImportPath (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:443:20)
    at PluginPass.enter (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:404:47)
    at newFn (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/visitors.js:177:21)
    at NodePath._call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:53:20)
    at NodePath.call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:40:17)
    at NodePath.visit (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:100:31)
    at TraversalContext.visitQueue (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:103:16)
    at TraversalContext.visitMultiple (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:72:17) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts'
  ]
}

Then I realized there is an undocumented evalImports , I also tried setting it to true:

skerrick 4321 $(pwd)/src/main.ts true
Click to expand!
--- Port: 4321
--- Entry point /var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts
--- Eval imports? true
code transformed:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.NestFactory = exports.APP_PIPE = exports.APP_INTERCEPTOR = exports.APP_GUARD = exports.APP_FILTER = void 0;

const tslib_1 = require("tslib");
/*
 * Nest @core
 * Copyright(c) 2017 - 2021 Kamil Mysliwiec
 * https://nestjs.com
 * MIT Licensed
 */


registerValue("/private/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/node_modules/@nestjs/core/index.js", "tslib_1", tslib_1);

require("reflect-metadata");

tslib_1.__exportStar(require("./adapters"), exports);

tslib_1.__exportStar(require("./application-config"), exports);

var constants_1 = require("./constants");

registerValue("/private/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/node_modules/@nestjs/core/index.js", "constants_1", constants_1);
Object.defineProperty(exports, "APP_FILTER", {
  enumerable: true,
  get: function () {
    return constants_1.APP_FILTER;
  }
});
Object.defineProperty(exports, "APP_GUARD", {
  enumerable: true,
  get: function () {
    return constants_1.APP_GUARD;
  }
});
Object.defineProperty(exports, "APP_INTERCEPTOR", {
  enumerable: true,
  get: function () {
    return constants_1.APP_INTERCEPTOR;
  }
});
Object.defineProperty(exports, "APP_PIPE", {
  enumerable: true,
  get: function () {
    return constants_1.APP_PIPE;
  }
});

tslib_1.__exportStar(require("./discovery"), exports);

tslib_1.__exportStar(require("./exceptions"), exports);

tslib_1.__exportStar(require("./helpers"), exports);

tslib_1.__exportStar(require("./injector"), exports);

tslib_1.__exportStar(require("./metadata-scanner"), exports);

tslib_1.__exportStar(require("./middleware"), exports);

tslib_1.__exportStar(require("./nest-application"), exports);

tslib_1.__exportStar(require("./nest-application-context"), exports);

var nest_factory_1 = require("./nest-factory");

registerValue("/private/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/node_modules/@nestjs/core/index.js", "nest_factory_1", nest_factory_1);
Object.defineProperty(exports, "NestFactory", {
  enumerable: true,
  get: function () {
    return nest_factory_1.NestFactory;
  }
});

tslib_1.__exportStar(require("./router"), exports);

return tslib_1.__exportStar(require("./services"), exports);

all imports Map(0) {}
ns imports for scope {}
ns for scope {}
Failed to normalize import path:  Error: Cannot find module './app.module'
Require stack:
- /var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.resolve (node:internal/modules/cjs/helpers:108:19)
    at normalizeImportPath (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:443:20)
    at PluginPass.enter (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:404:47)
    at newFn (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/visitors.js:177:21)
    at NodePath._call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:53:20)
    at NodePath.call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:40:17)
    at NodePath.visit (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:100:31)
    at TraversalContext.visitQueue (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:103:16)
    at TraversalContext.visitMultiple (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:72:17) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts'
  ]
}
/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/core/lib/transformation/index.js:45
    throw e;
    ^

Error: Cannot find module './app.module'
Require stack:
- /var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.resolve (node:internal/modules/cjs/helpers:108:19)
    at normalizeImportPath (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:443:20)
    at PluginPass.enter (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:404:47)
    at newFn (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/visitors.js:177:21)
    at NodePath._call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:53:20)
    at NodePath.call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:40:17)
    at NodePath.visit (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:100:31)
    at TraversalContext.visitQueue (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:103:16)
    at TraversalContext.visitMultiple (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:72:17) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts'
  ]
}

Maybe skerrick isn't supposed to work for projects like this? If that's the case, it may be nice to have a section describing under what circumstances skerrick works to the README.

Document Alternatives

The README should mention alternatives, and how this project compares to them.

This might be useful for gathering ideas/neat-features from other projects to implement in this project.

Error when exporting a nameless fn as default

export default function () { return 'this is changed' };

=>

TypeError: /home/anonimito/temp/temp-2.js: Cannot read properties of null (reading 'name')
    at PluginPass.ExportDefaultDeclaration (/home/anonimito/.nvs/node/17.3.0/x64/lib/node_modules/skerrick/dist/engine.js:346:43)
    at newFn (/home/anonimito/.nvs/node/17.3.0/x64/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/visitors.js:177:21)
    at NodePath._call (/home/anonimito/.nvs/node/17.3.0/x64/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:53:20)
    at NodePath.call (/home/anonimito/.nvs/node/17.3.0/x64/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:40:17)
    at NodePath.visit (/home/anonimito/.nvs/node/17.3.0/x64/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:100:31)
    at TraversalContext.visitQueue (/home/anonimito/.nvs/node/17.3.0/x64/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:103:16)
    at TraversalContext.visitMultiple (/home/anonimito/.nvs/node/17.3.0/x64/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:72:17)
    at TraversalContext.visit (/home/anonimito/.nvs/node/17.3.0/x64/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:129:19)
    at traverseNode (/home/anonimito/.nvs/node/17.3.0/x64/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/traverse-node.js:24:17)
    at NodePath.visit (/home/anonimito/.nvs/node/17.3.0/x64/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:107:52)

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.