Skip to content
This repository has been archived by the owner on Aug 7, 2023. It is now read-only.

Commit

Permalink
Merge pull request #119 from takbal/master
Browse files Browse the repository at this point in the history
a rewrite of the Julia side to use StaticLint.jl
  • Loading branch information
aminya authored Mar 9, 2021
2 parents 1f69228 + b17ce0b commit 47151f7
Show file tree
Hide file tree
Showing 10 changed files with 1,042 additions and 466 deletions.
14 changes: 2 additions & 12 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,16 @@ defaults: &defaults
- attach_workspace:
at: /tmp
- run:
name: Install Julia v1.2.0
name: Install Julia v1.5.3
command: |
curl -o julia.tar.gz --location --silent --show-error \
https://julialang-s3.julialang.org/bin/linux/x64/1.2/julia-1.2.0-linux-x86_64.tar.gz && \
https://julialang-s3.julialang.org/bin/linux/x64/1.5/julia-1.5.3-linux-x86_64.tar.gz && \
mkdir julia && \
tar --extract --gzip --strip 1 --directory=julia --file=julia.tar.gz && \
echo 'export PATH="/tmp/project/julia/bin:$PATH"' >> $BASH_ENV
- run:
name: Julia version
command: julia --version
- run:
name: Install Lint.jl
# Note the "using Lint" is to pre-compile the cache
# Also, we are using the `master` branch directly since a working
# version isn't currently released.
command: |
julia -E 'using Pkg; Pkg.add(PackageSpec(url="https://github.com/tonyhffong/Lint.jl", rev="master")); using Lint;'
- run:
name: Lint.jl version
command: julia -E 'using Pkg; Pkg.status("Lint");'
- run:
name: Create VFB for Atom to run in
command: /usr/local/bin/xvfb_start
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.DS_Store
npm-debug.log
node_modules
.package.json.full
57 changes: 36 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,60 @@
# linter-julia

:warning: This linter currently uses the old Lint.jl which does not work on the latest versions of Julia :warning:


This linter plugin for [AtomLinter](https://atomlinter.github.io/)
provides an interface to [Lint.jl](https://github.com/tonyhffong/Lint.jl).
provides an interface to [StaticLint.jl](https://github.com/julia-vscode/StaticLint.jl).
It will be used with files that have the `Julia` syntax.

![screenshot](https://raw.githubusercontent.com/AtomLinter/linter-julia/master/Screenshot.gif)
This is a fork that replaces Lint.jl with StaticLint.jl from the Julia VSCode plugin.

## Installation
![screenshot](https://raw.githubusercontent.com/takbal/linter-julia/master/Screenshot.gif)

- Install the package through Atom's UI and install the package.
## Developed on

You can also use the `apm` tool in the CLI:
```bash
$ apm install linter-julia
```
* julia-1.5.3
* [linter-ui-default](https://atom.io/packages/linter-ui-default)
* [linter](https://atom.io/packages/linter)
* tested on Ubuntu 18.04 and Windows

## Caveats

- You need to tell linter-julia where to find the julia executable
(i.e. `/usr/bin/julia` or `C:\Julia-1.3.0-rc4\bin\julia.exe`). See Settings below.
* The server needs a minute to spin up, then also some time to parse new Julia environments that this Atom instance
have not seen before. A pop-up is shown when parsing a new environment starts (but not when it ends). After parsing finishes, you need to
edit or reopen those files that are already in the editor for linting to start. If the environment had been already parsed, linting new files is immediate.
* The edited file has to be saved at least once for linting to start. This is by design of the linter package (https://github.com/steelbrain/linter/issues/1235)
* The environment for each file is guessed from its path. If this fails, Julia's default environment is assumed.
* The symbols are rebuilt if the modification time of the Project.toml or the Manifest.toml files change, for example,
you add, remove or update packages. Linting is not available during this rebuild.

- This package installs the master branch of Lint.jl automatically, to make it activated just restart Atom one more time! (two time total)
## Internals

The code generates its private shared environment at the Julia depot in 'environments/linter-julia'. It also places a logfile there.

- Note: if you have't installed [Juno](http://junolab.org/), and [Julia]( http://julialang.org/downloads/)
Guessing the environment works by walking upwards in the path and looking for Project.toml. If nothing found, the default
environment is assumed. The project's root file is then looked for at the canonical X/src/X.jl etc. locations.

- Note: If after two restarts the linter didn't work, add the Lint.jl manually:
```julia
] add https://github.com/tonyhffong/Lint.jl
I know nothing of Atom development or js, so the changes are likely messy there, please revise. Atom seems to be
unable to shut down the server process, so the server exits by polling Atom's PID right now.

## Installation

- Install the package through Atom's UI. You can also use the `apm` tool in the CLI:
```bash
$ apm install takbal/linter-julia
```

- You may need to tell linter-julia where to find the Julia executable
(i.e. `/usr/bin/julia` or `C:\Julia-1.5.3\bin\julia.exe`). The default assumes 'julia' just works.

- Julia must have the General registry added.

## Settings

![screenshot](https://raw.githubusercontent.com/AtomLinter/linter-julia/master/settings.png)

## Features

* By default linter-julia uses Juno's `julia`
* You can give a path to the `julia` executable that you want to use for Linting
* You can ignore the messages you don't need
* You can ignore the messages you don't need in settings. Provide the codes with a comma separated list.
The codes can be found by expanding the hover of the error message if 'show error codes' is set.

[Issues](https://github.com/AtomLinter/linter-julia/issues) and [pull requests]
(https://github.com/AtomLinter/linter-julia/pulls) are welcome.
Expand Down
Binary file modified Screenshot.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
89 changes: 71 additions & 18 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/* @flow */

import net from 'net';
import FS from 'fs';
import { CompositeDisposable } from 'atom';
import { spawnServer, terminateServer } from './server';
import type { Server } from './types';
import { spawnServer, getPipePath } from './server';

const pipepath = getPipePath();

let spawnedServer: ?Server = null;
let subscriptions: ?Object = null;

let executablePath;
Expand All @@ -14,25 +15,54 @@ let ignoreWarning;
let showErrorCodes;
let ignoreIssueCodes;

function timeout(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

async function pipeup() {
if (!FS.existsSync(pipepath)) {
await timeout(1000);
await pipeup();
}
}

async function unlock() {
if (global.linter_julia_locked === true) {
await timeout(200);
await unlock();
return;
}
global.linter_julia_locked = true;
}

export function activate() {
// eslint-disable-next-line global-require
require('atom-package-deps').install('linter-julia');
subscriptions = new CompositeDisposable();
subscriptions.add(
atom.config.observe('linter-julia.executablePath', async (value) => {
executablePath = value;
if (spawnedServer) {
// taken out: terminateServer() just does not work for some reason
/*
if (global.linter_julia_spawnedServer) {
try {
await terminateServer(spawnedServer);
spawnedServer = null;
spawnedServer = await spawnServer(executablePath);
await terminateServer(global.linter_julia_spawnedServer);
global.linter_julia_spawnedServer = spawnServer(executablePath);
global.linter_julia_started = true;
global.linter_julia_locked = false;
atom.notifications.addInfo(
'linter-julia: it is likely safer to restart Atom after this change');
} catch (e) {
const message = '[Linter-Julia] '
+ 'Unable to spawn server after config change';
atom.notifications.addError(`${message}. See console for details.`);
// eslint-disable-next-line no-console
console.error(`${message}: `, e);
}
}
*/
if (global.linter_julia_started) {
atom.notifications.addInfo('[Linter-Julia] please restart Atom for this change to work');
}
}),
atom.config.observe('linter-julia.ignoreInfo', (value) => {
Expand All @@ -48,12 +78,23 @@ export function activate() {
ignoreIssueCodes = value;
}),
);

// start only one server
if (typeof global.linter_julia_started === 'undefined') {
global.linter_julia_spawnedServer = spawnServer(executablePath);
global.linter_julia_started = true;
global.linter_julia_locked = false;
}
}

export function deactivate() {
if (spawnedServer) {
terminateServer(spawnedServer);
spawnedServer = null;
if (global.linter_julia_spawnedServer !== null) {
// terminateServer() just does not work
// terminateServer(global.linter_julia_spawnedServer);
// global.linter_julia_spawnedServer = null;
// global.linter_julia_started = false;
// server stays alive, just try not to deadlock
global.linter_julia_locked = false;
}
if (subscriptions) {
subscriptions.dispose();
Expand All @@ -67,10 +108,14 @@ export function provideLinter() {
lintsOnChange: true,
grammarScopes: ['source.julia'],
async lint(textEditor: Object) {
if (!spawnedServer) {
spawnedServer = await spawnServer(executablePath);
}
const connection = net.createConnection(spawnedServer.path);
// wait for the pipe to appear
await pipeup();

// only one connection at one time
await unlock();

const connection = net.createConnection(pipepath);

connection.on('connect', function writeData() {
this.write(JSON.stringify({
file: textEditor.getPath(),
Expand All @@ -87,7 +132,7 @@ export function provideLinter() {
// This is the timeout because net.Socket doesn't have one for connections
reject(new Error('Request timed out'));
connection.end();
}, 60 * 1000);
}, 300 * 1000);
connection.on('error', reject);

const data = [];
Expand All @@ -100,13 +145,21 @@ export function provideLinter() {
try {
parsed = JSON.parse(merged);
} catch (_) {
const msg = '[Linter-Julia] Server returned non-JSON response';
atom.notifications.addError(`${msg}. See console for more info`);
atom.notifications.addError(`[Linter-Julia] server has likely crashed. Please check symbolserver.log.${process.pid}
in the "linter-julia" shared Julia environment, and restart Atom.`);
// eslint-disable-next-line no-console
console.error(`${msg}: `, merged);
console.error('server returned: ', merged);
resolve(null);
return;
}
if (parsed.length > 0) {
if (parsed[0].description === 'I000') {
atom.notifications.addInfo(`[Linter-Julia] generating symbols for the environment ${parsed[0].excerpt}, please wait ...`);
parsed = [];
}
}

global.linter_julia_locked = false;
resolve(parsed);
});
}));
Expand Down
Loading

0 comments on commit 47151f7

Please sign in to comment.