Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support spellcheck and auto-educate quotes and dashes #130

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions app/main-process/appmenus.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const ipc = electron.ipcMain;
const dialog = electron.dialog;
const _ = require("lodash");
const Menu = electron.Menu;
const preferences = require("../renderer/preferences.js");

function setupMenus(callbacks) {
const template = [
Expand Down Expand Up @@ -102,6 +103,23 @@ function setupMenus(callbacks) {
accelerator: 'CmdOrCtrl+A',
role: 'selectall'
},
{
type: 'separator'
},
{
label: 'Spell Checking',
type: "checkbox",
checked: preferences.checkSpelling,
click: callbacks.toggleSpelling
},
{
label: 'Smart Quotes && Dashes',
type: "checkbox",
checked: preferences.smartQuotesAndDashes,
click(item) {
preferences.smartQuotesAndDashes = item.checked;
}
},
]
},
{
Expand Down Expand Up @@ -140,7 +158,7 @@ function setupMenus(callbacks) {
{
label: 'Tags visible',
type: "checkbox",
checked: true,
checked: preferences.tagsVisible,
click: callbacks.toggleTags
},
{
Expand Down Expand Up @@ -260,7 +278,7 @@ function setupMenus(callbacks) {
},
]
});

var windowMenu = _.find(template, menu => menu.role == "window");
windowMenu.submenu.push(
{
Expand Down
6 changes: 6 additions & 0 deletions app/main-process/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const electron = require('electron')
const app = electron.app
const ipc = electron.ipcMain;
const dialog = electron.dialog;
const preferences = require("../renderer/preferences.js");
const ProjectWindow = require("./projectWindow.js").ProjectWindow;
const DocumentationWindow = require("./documentationWindow.js").DocumentationWindow;
const AboutWindow = require("./aboutWindow.js").AboutWindow;
Expand Down Expand Up @@ -81,8 +82,13 @@ app.on('ready', function () {
if (win) win.exportJSOnly();
},
toggleTags: (item, focusedWindow, event) => {
preferences.tagsVisible = item.checked;
focusedWindow.webContents.send("set-tags-visible", item.checked);
},
toggleSpelling: (item, focusedWindow) => {
preferences.checkSpelling = item.checked;
focusedWindow.webContents.send("toggle-spell-check");
},
nextIssue: (item, focusedWindow) => {
focusedWindow.webContents.send("next-issue");
},
Expand Down
28 changes: 28 additions & 0 deletions app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@
"devDependencies": {
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"electron": "^1.4.3",
"electron": "^1.7.6",
"markdown-html": "^0.0.8",
"mocha": "^4.0.1",
"spectron": "^3.2.6"
},
"dependencies": {
"chokidar": "^1.6.0",
"fuzzaldrin-plus": "^0.5",
"electron-settings": "^3.1.4",
"glob": "^7.1.2",
"inkjs": "^1.6.0",
"lodash": "^4.13.1",
"mkdirp": "^0.5.1",
Expand Down
55 changes: 48 additions & 7 deletions app/renderer/contextmenu.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,54 @@
const {remote} = require('electron')
const {Menu, MenuItem} = remote
const SpellChecker = require('./spellChecker.js')

const menu = new Menu()
menu.append(new MenuItem({ role: 'cut' }))
menu.append(new MenuItem({ role: 'copy' }))
menu.append(new MenuItem({ role: 'paste' }))
menu.append(new MenuItem({ role: 'selectall' }))
const maxSpellingSuggestions = 4;

const playerViewMenu = new Menu()
playerViewMenu.append(new MenuItem({ role: 'copy' }))
playerViewMenu.append(new MenuItem({ role: 'selectall' }))

window.addEventListener('contextmenu', (e) => {
e.preventDefault()
menu.popup(remote.getCurrentWindow())
}, false);

const editor = ace.edit("editor")
if (e.target == editor.textInput.getElement()) {
var template = [
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
{ role: 'selectall' }
];

template = withSpellingSuggestions(template, editor)

const menu = Menu.buildFromTemplate(template)
menu.popup(remote.getCurrentWindow())
} else {
playerViewMenu.popup(remote.getCurrentWindow())
}
}, false);

function withSpellingSuggestions(template, editor) {
const pos = editor.getCursorPosition()
var suggestions = SpellChecker.getSuggestions(pos)
if (suggestions instanceof Array) {
suggestions = suggestions.slice(0, maxSpellingSuggestions).map(suggestion => {
return {
label: suggestion.word,
click() {
editor.getSession().getDocument().replace(suggestion.where, suggestion.word)
}
}
})
if (suggestions.length) {
suggestions.push({ type: 'separator' });
suggestions.push({ label: 'Ignore Spelling', click: () => SpellChecker.ignoreWordAt(pos) });
suggestions.push({ label: 'Learn Spelling', click: () => SpellChecker.learnWordAt(pos) });
} else {
suggestions = [{ label: 'No Guesses Found' }]
}
template = suggestions.concat({ type: 'separator' }, template)
}
return template
}
18 changes: 15 additions & 3 deletions app/renderer/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const ipc = electron.ipcRenderer;
const remote = electron.remote;
const path = require("path");
const $ = window.jQuery = require('./jquery-2.2.3.min.js');
const preferences = require('./preferences.js')

// Debug
const loadTestInk = false;
Expand All @@ -25,6 +26,8 @@ const LiveCompiler = require("./liveCompiler.js").LiveCompiler;
const InkProject = require("./inkProject.js").InkProject;
const NavHistory = require("./navHistory.js").NavHistory;
const GotoAnything = require("./goto.js").GotoAnything;
const SpellChecker = require("./spellChecker.js");
const QuotesAndDashes = require("./quotesAndDashes.js");

InkProject.setEvents({
"newProject": (project) => {
Expand All @@ -37,6 +40,7 @@ InkProject.setEvents({
NavView.setMainInkFilename(filename);
NavHistory.reset();
NavHistory.addStep();
SpellChecker.spellCheck(undefined, 0);
},
"didSave": () => {
var activeInk = InkProject.currentProject.activeInkFile;
Expand Down Expand Up @@ -66,6 +70,8 @@ $(document).ready(() => {
var testInk = require("fs").readFileSync(path.join(__dirname, "test.ink"), "utf8");
InkProject.currentProject.mainInk.setValue(testInk);
}

setTagsVisible(preferences.tagsVisible);
}
});

Expand Down Expand Up @@ -171,8 +177,10 @@ LiveCompiler.setEvents({
});

EditorView.setEvents({
"change": () => {
"change": (e) => {
LiveCompiler.setEdited();
SpellChecker.spellCheck(e);
QuotesAndDashes.smarten(e);
},
"jumpToSymbol": (symbolName, contextPos) => {
var foundSymbol = InkProject.currentProject.findSymbol(symbolName, contextPos);
Expand Down Expand Up @@ -246,8 +254,12 @@ GotoAnything.setEvents({
});

ipc.on("set-tags-visible", (event, visible) => {
if( visible )
setTagsVisible(visible);
});

function setTagsVisible(visible) {
if (visible)
$("#main").removeClass("hideTags");
else
$("#main").addClass("hideTags");
});
}
25 changes: 13 additions & 12 deletions app/renderer/editorView.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,25 @@ var savedScrollRow = null;
var events = {
change: () => {},
jumpToInclude: () => {},
jumpToSymbol: () => {}
jumpToSymbol: () => {},
navigate: () => {}
};

editor.setShowPrintMargin(false);
editor.setOptions({
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
});
editor.on("change", () => {
events.change();
editor.on("change", (e) => {
events.change(e);
});

// Exclude language_tools.textCompleter but add the Ink completer
editor.completers = editor.completers.filter(
(completer) => completer !== language_tools.textCompleter);
editor.completers.push(inkCompleter);

// Unfortunately standard jquery events don't work since
// Unfortunately standard jquery events don't work since
// Ace turns pointer events off
editor.on("click", function(e){

Expand Down Expand Up @@ -89,7 +90,7 @@ editor.on("mousemove", function (e) {
}
}
}

editor.renderer.setCursorStyle("default");
});

Expand Down Expand Up @@ -117,7 +118,7 @@ function addError(error) {
var aceClass = "ace-error";
var markerId = editor.session.addMarker(
new Range(error.lineNumber-1, 0, error.lineNumber, 0),
editorClass,
editorClass,
"line",
false
);
Expand Down Expand Up @@ -157,14 +158,14 @@ exports.EditorView = {
editor.focus();
},
focus: () => { editor.focus(); },
saveCursorPos: () => {
savedCursorPos = editor.getCursorPosition();
savedScrollRow = editor.getFirstVisibleRow();
saveCursorPos: () => {
savedCursorPos = editor.getCursorPosition();
savedScrollRow = editor.getFirstVisibleRow();
},
restoreCursorPos: () => {
restoreCursorPos: () => {
if( savedCursorPos ) {
editor.moveCursorToPosition(savedCursorPos);
editor.moveCursorToPosition(savedCursorPos);
editor.scrollToRow(savedScrollRow);
}
}
}
};
8 changes: 7 additions & 1 deletion app/renderer/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,12 @@ img.issue-icon.warning {
background: #bffff1;
}

#editor .ace-misspelled {
border-bottom: dotted 2px red;
margin-bottom: -1px;
position:absolute;
}

#editor .ace_gutter-layer {
background: white;
border-right: none;
Expand Down Expand Up @@ -731,7 +737,7 @@ img.issue-icon.warning {
}

#player td.expressionInput:focus {
outline: none;
outline: none;
}

#player .evaluationResult {
Expand Down
20 changes: 20 additions & 0 deletions app/renderer/preferences.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const settings = require('electron-settings');

const tagsVisibleKey = 'story.tagsVisible';
const smartQuotesAndDashesKey = 'editor.smartQuotesAndDashes';
const checkSpellingKey = 'editor.spelling.check';

Object.defineProperty(exports, 'tagsVisible', {
get: function () { return settings.get(tagsVisibleKey, true); },
set: function (value) { settings.set(tagsVisibleKey, value); }
});

Object.defineProperty(exports, 'smartQuotesAndDashes', {
get: function () { return settings.get(smartQuotesAndDashesKey, true); },
set: function (value) { settings.set(smartQuotesAndDashesKey, value); }
});

Object.defineProperty(exports, 'checkSpelling', {
get: function () { return settings.get(checkSpellingKey, true); },
set: function (value) { settings.set(checkSpellingKey, value); }
});
Loading