Skip to content

Commit 68558b6

Browse files
committed
Add some helper classes and editor features
1 parent 8113b4d commit 68558b6

6 files changed

Lines changed: 2013 additions & 29 deletions

File tree

build.gradle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ dependencies {
6161
compile 'org.codehaus.jettison:jettison:1.3.7'
6262

6363
testCompile 'junit:junit:4.12'
64-
testCompile 'org.apache.opennlp:opennlp-tools:1.6.0'
65-
6664
}
6765

6866
sourceSets {

src/main/java/com/jetbrains/idear/GoogleHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public static Pair<String, Double> getBestTextForUtterance(File file) {
7575
private static List<Pair<String, Double>> parseGSAPIResponse(String r) throws JSONException {
7676
List<Pair<String, Double>> res = new ArrayList<>();
7777
logger.log(Level.INFO, r);
78-
if (r.length() < 13) {
78+
if (r.length() < 30) {
7979
logger.log(Level.WARNING, "No result!");
8080
return res;
8181
}

src/main/java/com/jetbrains/idear/asr/ASRControlLoop.java

Lines changed: 66 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import java.util.Collection;
3131
import java.util.logging.Level;
3232
import java.util.logging.Logger;
33+
import java.util.regex.Matcher;
34+
import java.util.regex.Pattern;
3335

3436
import static com.jetbrains.idear.GoogleHelper.getBestTextForUtterance;
3537
import static java.awt.event.KeyEvent.*;
@@ -152,7 +154,7 @@ private void applyAction(String c) {
152154
} else if (c.endsWith("symbols")) {
153155
AsyncResult ar = ideService.invokeAction("AceJumpAction");
154156

155-
while(!ar.isProcessed()) {
157+
while (!ar.isProcessed()) {
156158
//Spin lock
157159
logger.info("Not done...");
158160
try {
@@ -195,11 +197,11 @@ private void applyAction(String c) {
195197
pressKeystroke(VK_TAB);
196198
} else if (c.contains(UNDO)) {
197199
ideService.invokeAction("$Undo");
198-
} else if(c.contains("shift")) {
200+
} else if (c.contains("shift")) {
199201
ideService.pressShift();
200202
}
201-
} else if(c.startsWith("release")) {
202-
if(c.contains("shift"))
203+
} else if (c.startsWith("release")) {
204+
if (c.contains("shift"))
203205
ideService.releaseShift();
204206
} else if (c.startsWith("following")) {
205207
if (c.endsWith("line")) {
@@ -212,6 +214,8 @@ private void applyAction(String c) {
212214
ideService.invokeAction("Diff.FocusOppositePane");
213215
} else if (c.endsWith("page")) {
214216
ideService.invokeAction("EditorPageDown");
217+
} else if (c.endsWith("word")) {
218+
ideService.type(VK_ALT, VK_RIGHT);
215219
}
216220
} else if (c.startsWith("previous")) {
217221
if (c.endsWith("line")) {
@@ -235,9 +239,10 @@ private void applyAction(String c) {
235239
ideService.invokeAction("CodeInspection.OnEditor");
236240
} else if (c.startsWith("speech pause")) {
237241
pauseSpeech();
238-
} else if(c.equals(SHOW_USAGES)) {
242+
} else if (c.equals(SHOW_USAGES)) {
239243
ideService.invokeAction("ShowUsages");
240-
} if (c.startsWith(OK_IDEA) || c.startsWith(OKAY_IDEA)) {
244+
}
245+
if (c.startsWith(OK_IDEA) || c.startsWith(OKAY_IDEA)) {
241246
beep();
242247
fireVoiceCommand();
243248
} else if (c.startsWith(OKAY_GOOGLE) || c.startsWith(OK_GOOGLE)) {
@@ -249,7 +254,8 @@ private void applyAction(String c) {
249254
ideService.invokeAction("ViewBreakpoints");
250255
}
251256
} else if (c.startsWith("debug")) {
252-
ideService.invokeAction("Debug");
257+
// ideService.invokeAction("Debug");
258+
ideService.type(VK_CONTROL, VK_SHIFT, VK_F9);
253259
} else if (c.startsWith("step")) {
254260
if (c.endsWith("over")) {
255261
ideService.invokeAction("StepOver");
@@ -269,32 +275,67 @@ private void applyAction(String c) {
269275
.getDataContextFromFocus()
270276
.doWhenDone((Consumer<DataContext>) dataContext -> run(nullCheckRecognizer, c, dataContext));
271277
}
272-
} else if(c.contains("tell me about yourself")) {
278+
} else if (c.contains("tell me about yourself")) {
273279
ApplicationInfo ai = ApplicationInfo.getInstance();
274280

275281
Calendar cal = ai.getBuildDate();
276282
SimpleDateFormat df = new SimpleDateFormat("EEEE, MMMM dd, yyyy");
277283

278284
say("My name is " + ai.getVersionName() + ", I was built on " + df.format(cal.getTime()) + ", I am running version " + ai.getApiVersion() + " of the IntelliJ Platform, and I am registered to " + ai.getCompanyName());
279-
} else if(c.contains("add new class")) {
285+
} else if (c.contains("add new class")) {
280286
ideService.invokeAction("NewElement");
281287
pressKeystroke(VK_ENTER);
282-
String className = getWebSpeechResult().first;
283-
if(className != null) {
284-
String camelCase = convertToCamelCase(className);
285-
logger.log(Level.INFO, "Class name: "+ camelCase);
288+
Pair<String, Double> className = getWebSpeechResult();
289+
if (className != null) {
290+
String camelCase = convertToCamelCase(className.first);
291+
logger.log(Level.INFO, "Class name: " + camelCase);
292+
camelCase = camelCase.substring(0, 1).toUpperCase() + camelCase.substring(1);
286293
ideService.type(camelCase);
287294
pressKeystroke(VK_ENTER);
288295
}
289-
} else if(c.contains("print line")) {
296+
} else if (c.contains("print line")) {
290297
ideService.type("sout");
291298
pressKeystroke(VK_TAB);
299+
} else if (c.contains("new string")) {
300+
Pair<String, Double> result = getWebSpeechResult();
301+
if (result != null) {
302+
ideService.type(VK_SHIFT, VK_QUOTE);
303+
ideService.type(result.first);
304+
ideService.type(VK_SHIFT, VK_QUOTE);
305+
}
306+
} else if (c.contains("enter ")) {
307+
Pair<String, Double> result = getWebSpeechResult();
308+
if (result != null) {
309+
if (c.endsWith("text")) {
310+
ideService.type(result.first);
311+
} else if (c.endsWith("camel case")) {
312+
ideService.type(convertToCamelCase(result.first));
313+
}
314+
}
315+
} else if (c.contains("public static void main")) {
316+
ideService.type("psvm");
317+
pressKeystroke(VK_TAB);
318+
} else if (c.endsWith("of line")) {
319+
if (c.startsWith("beginning")) {
320+
ideService.type(VK_META, VK_LEFT);
321+
} else if (c.startsWith("end")) {
322+
ideService.type(VK_META, VK_RIGHT);
323+
}
292324
}
293325
}
294326

295327
private String convertToCamelCase(String s) {
296-
String noSpaces = s.replaceAll("([\\W_]+)([a-zA-Z0-9])", "$2".toUpperCase());
297-
return noSpaces.substring(0, 1).toUpperCase() + noSpaces.substring(1);
328+
Matcher m = Pattern.compile("([\\s]+)([A-Za-z0-9])").matcher(s);
329+
StringBuilder sb = new StringBuilder();
330+
int last = 0;
331+
while (m.find()) {
332+
sb.append(s.substring(last, m.start()));
333+
sb.append(m.group(2).toUpperCase());
334+
last = m.end();
335+
}
336+
sb.append(s.substring(last));
337+
338+
return sb.toString();
298339
}
299340

300341
private void pressKeystroke(final int... keys) {
@@ -377,22 +418,22 @@ private void fireVoiceCommand() {
377418

378419
private void fireGoogleSearch() {
379420

380-
Pair<String, Double> searchQueryTuple = getWebSpeechResult();
381-
if (searchQueryTuple == null) return;
421+
Pair<String, Double> searchQueryTuple = getWebSpeechResult();
422+
if (searchQueryTuple == null) return;
382423

383-
ServiceManager
384-
.getService(TTSService.class)
385-
.say("I think you said " + searchQueryTuple.first + ", searching Google now");
424+
ServiceManager
425+
.getService(TTSService.class)
426+
.say("I think you said " + searchQueryTuple.first + ", searching Google now");
386427

387-
GoogleHelper.searchGoogle(searchQueryTuple.first);
428+
GoogleHelper.searchGoogle(searchQueryTuple.first);
388429
}
389430

390431
@Nullable
391432
private Pair<String, Double> getWebSpeechResult() {
392433
Pair<String, Double> searchQueryTuple = null;
393434
beep();
394435
try {
395-
searchQueryTuple = GoogleHelper.getBestTextForUtterance(CustomMicrophone.recordFromMic(GOOGLE_QUERY_DURATION));
436+
searchQueryTuple = GoogleHelper.getBestTextForUtterance(CustomMicrophone.recordFromMic(GOOGLE_QUERY_DURATION));
396437
} catch (IOException e) {
397438
logger.log(Level.SEVERE, "Panic! Failed to dump WAV", e);
398439
}
@@ -405,10 +446,12 @@ private Pair<String, Double> getWebSpeechResult() {
405446
}
406447

407448
private void pauseSpeech() {
449+
beep();
408450
String result;
409451
while (ListeningState.isActive()) {
410452
result = getResultFromRecognizer();
411453
if (result.equals("speech resume")) {
454+
beep();
412455
break;
413456
}
414457
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
3+
* Copyright (C) 2003-2016 The IdeaVim authors
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 2 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
package com.maddyhome.idea.vim.helper;
20+
21+
import org.jetbrains.annotations.NotNull;
22+
23+
/**
24+
* This helper class is used when working with various character level operations
25+
*/
26+
public class CharacterHelper {
27+
28+
public static enum CharacterType {
29+
LETTER_OR_DIGIT,
30+
HIRAGANA,
31+
KATAKANA,
32+
HALF_WIDTH_KATAKANA,
33+
PUNCTUATION,
34+
WHITESPACE
35+
}
36+
37+
public static final char CASE_TOGGLE = '~';
38+
public static final char CASE_UPPER = 'u';
39+
public static final char CASE_LOWER = 'l';
40+
41+
/**
42+
* This returns the type of the supplied character. The logic is as follows:<br>
43+
* If the character is whitespace, <code>WHITESPACE</code> is returned.<br>
44+
* If the punctuation is being skipped or the character is a letter, digit, or underscore, <code>LETTER_OR_DIGIT</code>
45+
* is returned.<br>
46+
* Otherwise <code>PUNCTUATION</code> is returned.
47+
*
48+
* @param ch The character to analyze
49+
* @param punctuationAsLetters True if punctuation is to be ignored, false if not
50+
* @return The type of the character
51+
*/
52+
@NotNull
53+
public static CharacterType charType(char ch, boolean punctuationAsLetters) {
54+
final Character.UnicodeBlock block = Character.UnicodeBlock.of(ch);
55+
if (Character.isWhitespace(ch)) {
56+
return CharacterType.WHITESPACE;
57+
}
58+
else if (block == Character.UnicodeBlock.HIRAGANA) {
59+
return CharacterType.HIRAGANA;
60+
}
61+
else if (block == Character.UnicodeBlock.KATAKANA) {
62+
return CharacterType.KATAKANA;
63+
}
64+
else if (isHalfWidthKatakanaLetter(ch)) {
65+
return CharacterType.HALF_WIDTH_KATAKANA;
66+
}
67+
else if (punctuationAsLetters || Character.isLetterOrDigit(ch) || ch == '_') {
68+
return CharacterType.LETTER_OR_DIGIT;
69+
}
70+
else {
71+
return CharacterType.PUNCTUATION;
72+
}
73+
}
74+
75+
private static boolean isHalfWidthKatakanaLetter(char ch) {
76+
return ch >= '\uFF66' && ch <= '\uFF9F';
77+
}
78+
79+
/**
80+
* Changes the case of the supplied character based on the supplied change type
81+
*
82+
* @param ch The character to change
83+
* @param type One of <code>CASE_TOGGLE</code>, <code>CASE_UPPER</code>, or <code>CASE_LOWER</code>
84+
* @return The character with changed case or the original if not a letter
85+
*/
86+
public static char changeCase(char ch, char type) {
87+
switch (type) {
88+
case CASE_TOGGLE:
89+
if (Character.isLowerCase(ch)) {
90+
ch = Character.toUpperCase(ch);
91+
}
92+
else if (Character.isUpperCase(ch)) {
93+
ch = Character.toLowerCase(ch);
94+
}
95+
break;
96+
case CASE_LOWER:
97+
ch = Character.toLowerCase(ch);
98+
break;
99+
case CASE_UPPER:
100+
ch = Character.toUpperCase(ch);
101+
break;
102+
}
103+
104+
return ch;
105+
}
106+
}

0 commit comments

Comments
 (0)