File indexing completed on 2024-04-28 05:49:01
0001 /* 0002 * SPDX-FileCopyrightText: 2022 Mark Nauwelaerts <mark.nauwelaerts@gmail.com> 0003 * 0004 * SPDX-License-Identifier: MIT 0005 */ 0006 0007 #include "lspclientutils.h" 0008 0009 #include <KTextEditor/Document> 0010 0011 LSPRange transformRange(const QUrl &url, const LSPClientRevisionSnapshot &snapshot, const LSPRange &range) 0012 { 0013 KTextEditor::Document *doc; 0014 qint64 revision; 0015 0016 auto result = range; 0017 snapshot.find(url, doc, revision); 0018 if (doc) { 0019 doc->transformRange(result, KTextEditor::MovingRange::DoNotExpand, KTextEditor::MovingRange::AllowEmpty, revision); 0020 } 0021 return result; 0022 } 0023 0024 void applyEdits(KTextEditor::Document *doc, const LSPClientRevisionSnapshot *snapshot, const QList<LSPTextEdit> &edits) 0025 { 0026 // NOTE: 0027 // server might be pretty sloppy wrt edits (e.g. python-language-server) 0028 // e.g. send one edit for the whole document rather than 'surgical edits' 0029 // and that even when requesting format for a limited selection 0030 // ... but then we are but a client and do as we are told 0031 // all-in-all a low priority feature 0032 0033 // all coordinates in edits are wrt original document, 0034 // so create moving ranges that will adjust to preceding edits as they are applied 0035 QList<KTextEditor::MovingRange *> ranges; 0036 for (const auto &edit : edits) { 0037 auto range = snapshot ? transformRange(doc->url(), *snapshot, edit.range) : edit.range; 0038 KTextEditor::MovingRange *mr = doc->newMovingRange(range); 0039 ranges.append(mr); 0040 } 0041 0042 // now make one transaction (a.o. for one undo) and apply in sequence 0043 if (!ranges.empty()) { 0044 KTextEditor::Document::EditingTransaction transaction(doc); 0045 for (int i = 0; i < ranges.length(); ++i) { 0046 doc->replaceText(ranges.at(i)->toRange(), edits.at(i).newText); 0047 } 0048 } 0049 0050 qDeleteAll(ranges); 0051 }