add underline to indicate current ime input
This commit is contained in:
parent
3ed5701621
commit
f8f5b7b0d8
1
NEWS.md
1
NEWS.md
|
@ -19,6 +19,7 @@ Version 0.6.0
|
||||||
- fix: code fold parsing not correct
|
- fix: code fold parsing not correct
|
||||||
- enhancement: support #include_next (and clang libc++)
|
- enhancement: support #include_next (and clang libc++)
|
||||||
- fix: hide popup windows when the editor is closed
|
- fix: hide popup windows when the editor is closed
|
||||||
|
- enhancement: show pinyin when input chinese characters
|
||||||
|
|
||||||
Version 0.5.0
|
Version 0.5.0
|
||||||
- enhancement: support C++ using type alias;
|
- enhancement: support C++ using type alias;
|
||||||
|
|
|
@ -1020,49 +1020,40 @@ void Editor::mouseReleaseEvent(QMouseEvent *event)
|
||||||
|
|
||||||
void Editor::inputMethodEvent(QInputMethodEvent *event)
|
void Editor::inputMethodEvent(QInputMethodEvent *event)
|
||||||
{
|
{
|
||||||
bool handled = false;
|
SynEdit::inputMethodEvent(event);
|
||||||
auto action = finally([this,&handled,event](){
|
QString s = event->commitString();
|
||||||
if (!handled)
|
if (s.isEmpty())
|
||||||
SynEdit::inputMethodEvent(event);
|
return;
|
||||||
});
|
|
||||||
if (pMainWindow->completionPopup()->isVisible()) {
|
if (pMainWindow->completionPopup()->isVisible()) {
|
||||||
if (onCompletionInputMethod(event)) {
|
onCompletionInputMethod(event);
|
||||||
handled = true;
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
QString s = event->commitString();
|
mLastIdCharPressed+=s.length();
|
||||||
if (!s.isEmpty()) {
|
if (pSettings->codeCompletion().enabled()
|
||||||
mLastIdCharPressed+=s.length();
|
&& pSettings->codeCompletion().showCompletionWhileInput() ) {
|
||||||
if (pSettings->codeCompletion().enabled()
|
if (mLastIdCharPressed>=1) {
|
||||||
&& pSettings->codeCompletion().showCompletionWhileInput() ) {
|
QString lastWord = getPreviousWordAtPositionForSuggestion(caretXY());
|
||||||
if (mLastIdCharPressed>=1) {
|
if (!lastWord.isEmpty()) {
|
||||||
QString lastWord = getPreviousWordAtPositionForSuggestion(caretXY());
|
if (CppTypeKeywords.contains(lastWord)) {
|
||||||
if (!lastWord.isEmpty()) {
|
return;
|
||||||
if (CppTypeKeywords.contains(lastWord)) {
|
}
|
||||||
return;
|
PStatement statement = mParser->findStatementOf(
|
||||||
}
|
mFilename,
|
||||||
PStatement statement = mParser->findStatementOf(
|
lastWord,
|
||||||
mFilename,
|
caretY());
|
||||||
lastWord,
|
StatementKind kind = mParser->getKindOfStatement(statement);
|
||||||
caretY());
|
if (kind == StatementKind::skClass
|
||||||
StatementKind kind = mParser->getKindOfStatement(statement);
|
|| kind == StatementKind::skEnumClassType
|
||||||
if (kind == StatementKind::skClass
|
|| kind == StatementKind::skEnumType
|
||||||
|| kind == StatementKind::skEnumClassType
|
|| kind == StatementKind::skTypedef) {
|
||||||
|| kind == StatementKind::skEnumType
|
//last word is a typedef/class/struct, this is a var or param define, and dont show suggestion
|
||||||
|| kind == StatementKind::skTypedef) {
|
// if devEditor.UseTabnine then
|
||||||
//last word is a typedef/class/struct, this is a var or param define, and dont show suggestion
|
// ShowTabnineCompletion;
|
||||||
// if devEditor.UseTabnine then
|
return;
|
||||||
// ShowTabnineCompletion;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
setSelText(s);
|
|
||||||
showCompletion(false);
|
|
||||||
handled = true;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
showCompletion(false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2424,7 +2415,6 @@ bool Editor::onCompletionInputMethod(QInputMethodEvent *event)
|
||||||
return processed;
|
return processed;
|
||||||
QString s=event->commitString();
|
QString s=event->commitString();
|
||||||
if (!s.isEmpty()) {
|
if (!s.isEmpty()) {
|
||||||
setSelText(s);
|
|
||||||
BufferCoord pBeginPos,pEndPos;
|
BufferCoord pBeginPos,pEndPos;
|
||||||
QString phrase = getWordAtPosition(this,caretXY(),
|
QString phrase = getWordAtPosition(this,caretXY(),
|
||||||
pBeginPos,pEndPos,
|
pBeginPos,pEndPos,
|
||||||
|
|
|
@ -2137,6 +2137,24 @@ bool SynEdit::canDoBlockIndent()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRect SynEdit::calculateCaretRect()
|
||||||
|
{
|
||||||
|
DisplayCoord coord = displayXY();
|
||||||
|
if (!mInputPreeditString.isEmpty()) {
|
||||||
|
QString sLine = lineText().left(mCaretX-1)
|
||||||
|
+ mInputPreeditString
|
||||||
|
+ lineText().mid(mCaretX-1);
|
||||||
|
coord.Column = charToColumn(sLine,mCaretX+mInputPreeditString.length());
|
||||||
|
}
|
||||||
|
QPoint caretPos = rowColumnToPixels(coord);
|
||||||
|
int caretWidth=mCharWidth;
|
||||||
|
if (mCaretY <= mLines->count() && mCaretX <= mLines->getString(mCaretY-1).length()) {
|
||||||
|
caretWidth = charColumns(mLines->getString(mCaretY-1)[mCaretX-1])*mCharWidth;
|
||||||
|
}
|
||||||
|
return QRect(caretPos.x(),caretPos.y(),caretWidth,
|
||||||
|
mTextHeight);
|
||||||
|
}
|
||||||
|
|
||||||
void SynEdit::clearAreaList(SynEditingAreaList areaList)
|
void SynEdit::clearAreaList(SynEditingAreaList areaList)
|
||||||
{
|
{
|
||||||
areaList.clear();
|
areaList.clear();
|
||||||
|
@ -2687,16 +2705,7 @@ void SynEdit::updateScrollbars()
|
||||||
void SynEdit::updateCaret()
|
void SynEdit::updateCaret()
|
||||||
{
|
{
|
||||||
mStateFlags.setFlag(SynStateFlag::sfCaretChanged,false);
|
mStateFlags.setFlag(SynStateFlag::sfCaretChanged,false);
|
||||||
DisplayCoord coord = displayXY();
|
invalidateRect(calculateCaretRect());
|
||||||
QPoint caretPos = rowColumnToPixels(coord);
|
|
||||||
int caretWidth=mCharWidth;
|
|
||||||
//qDebug()<<"caret"<<mCaretX<<mCaretY;
|
|
||||||
if (mCaretY <= mLines->count() && mCaretX <= mLines->getString(mCaretY-1).length()) {
|
|
||||||
caretWidth = charColumns(mLines->getString(mCaretY-1)[mCaretX-1])*mCharWidth;
|
|
||||||
}
|
|
||||||
QRect rcCaret(caretPos.x(),caretPos.y(),caretWidth,
|
|
||||||
mTextHeight);
|
|
||||||
invalidateRect(rcCaret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynEdit::recalcCharExtent()
|
void SynEdit::recalcCharExtent()
|
||||||
|
@ -5325,14 +5334,7 @@ void SynEdit::paintEvent(QPaintEvent *event)
|
||||||
QPainter painter(viewport());
|
QPainter painter(viewport());
|
||||||
//Get the invalidated rect.
|
//Get the invalidated rect.
|
||||||
QRect rcClip = event->rect();
|
QRect rcClip = event->rect();
|
||||||
DisplayCoord coord = displayXY();
|
QRect rcCaret = calculateCaretRect();
|
||||||
QPoint caretPos = rowColumnToPixels(coord);
|
|
||||||
int caretWidth=mCharWidth;
|
|
||||||
if (mCaretY <= mLines->count() && mCaretX <= mLines->getString(mCaretY-1).length()) {
|
|
||||||
caretWidth = charColumns(mLines->getString(mCaretY-1)[mCaretX-1])*mCharWidth;
|
|
||||||
}
|
|
||||||
QRect rcCaret(caretPos.x(),caretPos.y(),caretWidth,
|
|
||||||
mTextHeight);
|
|
||||||
|
|
||||||
if (rcCaret == rcClip) {
|
if (rcCaret == rcClip) {
|
||||||
// only update caret
|
// only update caret
|
||||||
|
@ -5595,6 +5597,15 @@ void SynEdit::mouseDoubleClickEvent(QMouseEvent *event)
|
||||||
|
|
||||||
void SynEdit::inputMethodEvent(QInputMethodEvent *event)
|
void SynEdit::inputMethodEvent(QInputMethodEvent *event)
|
||||||
{
|
{
|
||||||
|
qDebug()<<"---";
|
||||||
|
qDebug()<<event->replacementStart()<<":"<<event->replacementLength()<<" - "
|
||||||
|
<< event->preeditString()<<" - "<<event->commitString();
|
||||||
|
|
||||||
|
QString oldString = mInputPreeditString;
|
||||||
|
mInputPreeditString = event->preeditString();
|
||||||
|
if (oldString!=mInputPreeditString) {
|
||||||
|
invalidateLine(mCaretY);
|
||||||
|
}
|
||||||
QString s = event->commitString();
|
QString s = event->commitString();
|
||||||
if (!s.isEmpty()) {
|
if (!s.isEmpty()) {
|
||||||
commandProcessor(SynEditorCommand::ecImeStr,QChar(),&s);
|
commandProcessor(SynEditorCommand::ecImeStr,QChar(),&s);
|
||||||
|
|
|
@ -505,6 +505,8 @@ private:
|
||||||
BufferCoord getPreviousLeftBracket(int x,int y);
|
BufferCoord getPreviousLeftBracket(int x,int y);
|
||||||
bool canDoBlockIndent();
|
bool canDoBlockIndent();
|
||||||
|
|
||||||
|
QRect calculateCaretRect();
|
||||||
|
|
||||||
//Commands
|
//Commands
|
||||||
void doDeleteLastChar();
|
void doDeleteLastChar();
|
||||||
void doDeleteCurrentChar();
|
void doDeleteCurrentChar();
|
||||||
|
@ -668,6 +670,8 @@ private:
|
||||||
|
|
||||||
QCursor mDefaultCursor;
|
QCursor mDefaultCursor;
|
||||||
|
|
||||||
|
QString mInputPreeditString;
|
||||||
|
|
||||||
friend class SynEditTextPainter;
|
friend class SynEditTextPainter;
|
||||||
|
|
||||||
// QWidget interface
|
// QWidget interface
|
||||||
|
|
|
@ -731,6 +731,10 @@ void SynEditTextPainter::PaintLines()
|
||||||
sLine = edit->mLines->getString(vLine - 1);
|
sLine = edit->mLines->getString(vLine - 1);
|
||||||
// determine whether will be painted with ActiveLineColor
|
// determine whether will be painted with ActiveLineColor
|
||||||
bCurrentLine = (edit->mCaretY == vLine);
|
bCurrentLine = (edit->mCaretY == vLine);
|
||||||
|
if (bCurrentLine && !edit->mInputPreeditString.isEmpty()) {
|
||||||
|
sLine = sLine.left(edit->mCaretX-1) + edit->mInputPreeditString
|
||||||
|
+ sLine.mid(edit->mCaretX-1);
|
||||||
|
}
|
||||||
// Initialize the text and background colors, maybe the line should
|
// Initialize the text and background colors, maybe the line should
|
||||||
// use special values for them.
|
// use special values for them.
|
||||||
colFG = edit->palette().color(QPalette::Text);
|
colFG = edit->palette().color(QPalette::Text);
|
||||||
|
@ -792,7 +796,11 @@ void SynEditTextPainter::PaintLines()
|
||||||
rcToken = rcLine;
|
rcToken = rcLine;
|
||||||
if (!edit->mHighlighter || !edit->mHighlighter->enabled()) {
|
if (!edit->mHighlighter || !edit->mHighlighter->enabled()) {
|
||||||
sToken = sLine;
|
sToken = sLine;
|
||||||
nTokenColumnLen = edit->mLines->lineColumns(vLine-1);
|
if (bCurrentLine) {
|
||||||
|
nTokenColumnLen = edit->stringColumns(sLine,0);
|
||||||
|
} else {
|
||||||
|
nTokenColumnLen = edit->mLines->lineColumns(vLine-1);
|
||||||
|
}
|
||||||
if (edit->mOptions.testFlag(eoShowSpecialChars) && (!bLineSelected) && (!bSpecialLine) && (nTokenColumnLen < vLastChar)) {
|
if (edit->mOptions.testFlag(eoShowSpecialChars) && (!bLineSelected) && (!bSpecialLine) && (nTokenColumnLen < vLastChar)) {
|
||||||
sToken = sToken + SynLineBreakGlyph;
|
sToken = sToken + SynLineBreakGlyph;
|
||||||
nTokenColumnLen += edit->charColumns(SynLineBreakGlyph);
|
nTokenColumnLen += edit->charColumns(SynLineBreakGlyph);
|
||||||
|
@ -845,7 +853,7 @@ void SynEditTextPainter::PaintLines()
|
||||||
throw BaseError(SynEdit::tr("The highlighter seems to be in an infinite loop"));
|
throw BaseError(SynEdit::tr("The highlighter seems to be in an infinite loop"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nTokenColumnsBefore = edit->charToColumn(vLine,edit->mHighlighter->getTokenPos()+1)-1;
|
nTokenColumnsBefore = edit->charToColumn(sLine,edit->mHighlighter->getTokenPos()+1)-1;
|
||||||
nTokenColumnLen = edit->stringColumns(sToken, nTokenColumnsBefore);
|
nTokenColumnLen = edit->stringColumns(sToken, nTokenColumnsBefore);
|
||||||
if (nTokenColumnsBefore + nTokenColumnLen >= vFirstChar) {
|
if (nTokenColumnsBefore + nTokenColumnLen >= vFirstChar) {
|
||||||
if (nTokenColumnsBefore + nTokenColumnLen >= vLastChar) {
|
if (nTokenColumnsBefore + nTokenColumnLen >= vLastChar) {
|
||||||
|
@ -914,6 +922,14 @@ void SynEditTextPainter::PaintLines()
|
||||||
PaintHighlightToken(true);
|
PaintHighlightToken(true);
|
||||||
|
|
||||||
//Paint editingAreaBorders
|
//Paint editingAreaBorders
|
||||||
|
if (bCurrentLine && edit->mInputPreeditString.length()>0) {
|
||||||
|
PSynEditingArea area = std::make_shared<SynEditingArea>();
|
||||||
|
area->beginX = edit->mCaretX;
|
||||||
|
area->endX = edit->mCaretX + edit->mInputPreeditString.length();
|
||||||
|
area->type = SynEditingAreaType::eatUnderLine;
|
||||||
|
area->color = colFG;
|
||||||
|
areaList.append(area);
|
||||||
|
}
|
||||||
PaintEditAreas(areaList);
|
PaintEditAreas(areaList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue