Community
    • 登入

    Replace current line without inserting a new line

    已排程 已置頂 已鎖定 已移動 Help wanted · · · – – – · · ·
    31 貼文 5 Posters 27.5k 瀏覽
    正在載入更多貼文
    • 從舊到新
    • 從新到舊
    • 最多點贊
    回覆
    • 在新貼文中回覆
    登入後回覆
    此主題已被刪除。只有擁有主題管理權限的使用者可以查看。
    • YaronY
      Yaron
      最後由 編輯

      Hello,

      A Python script to replace the current line with the clipboard content:

      editor.lineEnd()
      editor.homeExtend()
      
      editor.paste()
      

      I’d like to avoid inserting a new line on pasting.
      The following code works but there’s probably a better way.

      currentLine = editor.lineFromPosition(editor.getCurrentPos())
      
      editor.lineEnd()
      editor.homeExtend()
      
      editor.paste()
      
      currentPos = editor.getCurrentPos()
      
      if currentLine != editor.lineFromPosition(currentPos) and editor.getColumn(currentPos) == 0:
      	editor.lineDelete() 
      

      I’d appreciate your help.

      1 條回覆 最後回覆 回覆 引用 0
      • Scott SumnerS
        Scott Sumner
        最後由 編輯

        We’re not playing Golf here, but how about this:

        editor.deleteLine(editor.lineFromPosition(editor.getCurrentPos()))
        editor.paste()
        

        This may be obvious, but if what you have in the clipboard has a “line ending” at its end, you’ll get it in your paste into Notepad++. Just be sure that you know where the line-ending you’re trying to avoid is coming from! :)

        1 條回覆 最後回覆 回覆 引用 0
        • YaronY
          Yaron
          最後由 編輯

          Hello Scott Sumner,

          Thanks for your suggestion. I appreciate it.

          But if there isn’t an EOL in the clipboard you’re pasting into the wrong hole. :)

          Best regards.

          Scott SumnerS 1 條回覆 最後回覆 回覆 引用 0
          • Scott SumnerS
            Scott Sumner @Yaron
            最後由 編輯

            @Yaron

            I guess I misunderstood the requirements, but hopefully it got you farther along in what you’re doing. You can do an editor.addText(‘\r\n’) [if using Windows file format] after the paste, but then there is the question of where do you want your caret to end up, which I don’t know.

            Here’s a semi-related problem I haven’t been able to solve well: You can’t tell what is in the clipboard before you paste it. So, perhaps there is a line-ending at the end of it, perhaps not. You have to paste it and then you can find out by what ends up in your document and maybe delete (programmatically) what you don’t want, but you have to figure out how long the pasted text was, etc,. and it is all just seemingly over-complicated. There should be .getClipboardText() and .setClipboardText(txt) functions…which would make life easier.

            Happy Scripting!

            1 條回覆 最後回覆 回覆 引用 0
            • YaronY
              Yaron
              最後由 編輯

              Hello Scott,

              You can’t tell what is in the clipboard before you paste it.

              This confirmation is important.
              Indeed, the easiest way would be checking for an EOL in the clipboard content.
              (Actually it would be better to make sure it’s text but I wanted a simple practical solution.
              And there’s Undo as well…).

              You’ve been helpful. Thanks again.

              Best regards.

              1 條回覆 最後回覆 回覆 引用 0
              • YaronY
                Yaron
                最後由 編輯

                Slightly better. :)

                oldLine = editor.lineFromPosition(editor.getCurrentPos())
                
                editor.beginUndoAction()
                
                editor.lineEnd()
                editor.homeExtend()
                
                editor.paste()
                
                newPos = editor.getCurrentPos()
                
                if oldLine != editor.lineFromPosition(newPos) and editor.getColumn(newPos) == 0:
                	editor.lineUp()
                	editor.lineEnd()	# Always position the carret at the end of the pasted string.
                	notepad.menuCommand(MENUCOMMAND.EDIT_DELETE)	# Remove inserted new line even if the replaced line is last in the file.
                
                editor.endUndoAction()
                
                Claudia FrankC 1 條回覆 最後回覆 回覆 引用 0
                • Claudia FrankC
                  Claudia Frank @Yaron
                  最後由 編輯

                  Yaron, are you sure your logic is correct?

                  if oldLine != editor.lineFromPosition(newPos) and editor.getColumn(newPos) == 0:
                  

                  You compare a number against boolean result.
                  If there is a need to check if the clipboard has text and an eol added you might think of
                  using ctypes and openclipboard api function. But don’t know if this isn’t overkill.

                  Scott, curious, what does this mean?

                  We’re not playing Golf here
                  

                  Thanks and cheers
                  Claudia

                  Scott SumnerS 1 條回覆 最後回覆 回覆 引用 0
                  • Scott SumnerS
                    Scott Sumner @Claudia Frank
                    最後由 編輯

                    @Claudia-Frank ,

                    My reference to “golf” was because my reply to Yaron (which apparently wasn’t quite what he needed) was a very short one-liner…“golf” is a game where someone proposes a programming task, and then people reply with their shortest versions. Here’s a better explanation: https://en.wikipedia.org/wiki/Code_golf

                    I’ve had difficulty getting clipboard functionality into my pythonscripts. I tried the advice found in the early part of the thread found here (https://sourceforge.net/p/npppythonscript/discussion/1188886/thread/bafe5a3a/), and actually had it working at one point, then got a new job and a different computer, and I could never get it working again (as you can see at the end of the thread).

                    Claudia FrankC 1 條回覆 最後回覆 回覆 引用 0
                    • Claudia FrankC
                      Claudia Frank @Scott Sumner
                      最後由 編輯

                      @Scott-Sumner
                      :-) I see, thanks.
                      In regards to clipboard, gimme a second …

                      Cheers
                      Claudia

                      1 條回覆 最後回覆 回覆 引用 0
                      • Scott SumnerS
                        Scott Sumner
                        最後由 編輯

                        Also, Claudia, how is Yaron comparing a number against a boolean? His line you reference appears to be okay to me, syntax-wise.

                        1 條回覆 最後回覆 回覆 引用 0
                        • YaronY
                          Yaron
                          最後由 編輯

                          Hello Claudia and Scott,

                          @Claudia,
                          Scott has already asked it: where is the boolean?

                          But don’t know if this isn’t overkill.

                          I’m afraid it would. :)

                          @Scott,
                          As I’ve mentioned before - your statement regarding the clipboard was helpful indeed.

                          Thank you both very much.
                          Best regards.

                          1 條回覆 最後回覆 回覆 引用 0
                          • Claudia FrankC
                            Claudia Frank
                            最後由 Claudia Frank 編輯

                            Hello Yaron and Scott,

                            a quick script to get the clipboard data using ctypes and windows api.
                            Tested on Ubuntu (Linux) with wine - hopefully this works on real windows as well.

                            import ctypes
                            
                            def Get():
                                if ctypes.windll.user32.OpenClipboard(None):
                                    clipboard_handle = ctypes.windll.user32.GetClipboardData(1)
                                    if clipboard_handle:
                                        pointer_to_content = ctypes.windll.kernel32.GlobalLock(clipboard_handle)
                                        clipboard_data = ctypes.c_char_p(pointer_to_content).value
                                        ctypes.windll.kernel32.GlobalUnlock(clipboard_handle)
                                    else:
                                        return 'invalid handle'
                                    ctypes.windll.user32.CloseClipboard()
                                    return clipboard_data
                                else:
                                    return 'ERROR'
                            
                            print Get()
                            

                            In reality you would make sure that the openclipboard would be called more often
                            if it fails on the first try, as it might be that another application currently has opened it
                            and therefore your app doesn’t get access.

                            if oldLine != editor.lineFromPosition(newPos) and editor.getColumn(newPos) == 0:
                            

                            execution in order (afaik)
                            First, both functions get executed
                            Second result from getColumn get compared against 0 ->returns boolead
                            Third result from lineFrom… gets ANDed with boolean -> retruns boolean
                            Last oldLine(number) gets checked against boolean -> which means a boolean
                            compare at all. All oldLine numbers are True execept the first line which is 0 and treaten
                            as False.

                            As said, afaik. Maybe I’m wrong.

                            Cheers
                            Claudia

                            1 條回覆 最後回覆 回覆 引用 1
                            • YaronY
                              Yaron
                              最後由 編輯

                              Hello Claudia,

                              Thank you very much for the script.
                              I won’t be by a PC until Monday or Tuesday. I’ll try it then.

                              And as I’ve written to Scott: it’s good to know I haven’t missed anything too simple. :)
                              I appreciate it.

                              First, both functions get executed

                              I think there’s no need to execute the second function if the first condition is not true.
                              So, the order is:
                              Execute first function.
                              Check first condition.
                              Execute second function.
                              Check second condition.

                              What do you think?

                              BR.

                              Claudia FrankC 1 條回覆 最後回覆 回覆 引用 0
                              • Claudia FrankC
                                Claudia Frank @Yaron
                                最後由 編輯

                                @Yaron and Scott,

                                of course, you are right.
                                Phew - one of these days …
                                Please forgive and forget what I said.
                                Recently I was reading something about precedence and that If statement
                                has one of the lowest rating, but of course != get executed before.
                                I guess now its time to go to bed. ;-)

                                Cheers
                                Claudia

                                1 條回覆 最後回覆 回覆 引用 0
                                • Claudia FrankC
                                  Claudia Frank
                                  最後由 編輯

                                  Btw… here the confirmation that you are right.

                                    2           0 LOAD_GLOBAL              0 (oldLine)
                                                3 LOAD_GLOBAL              1 (editor)
                                                6 LOAD_ATTR                2 (lineFromPosition)
                                                9 LOAD_GLOBAL              3 (newPos)
                                               12 CALL_FUNCTION            1
                                               15 COMPARE_OP               3 (!=)
                                               18 POP_JUMP_IF_FALSE       50
                                               21 LOAD_GLOBAL              1 (editor)
                                               24 LOAD_ATTR                4 (getColumn)
                                               27 LOAD_GLOBAL              3 (newPos)
                                               30 CALL_FUNCTION            1
                                               33 LOAD_CONST               1 (0)
                                               36 COMPARE_OP               2 (==)
                                               39 POP_JUMP_IF_FALSE       50
                                  
                                    3          42 LOAD_CONST               2 ('y')
                                               45 PRINT_ITEM          
                                               46 PRINT_NEWLINE       
                                               47 JUMP_FORWARD             5 (to 55)
                                  
                                    5     >>   50 LOAD_CONST               3 ('n')
                                               53 PRINT_ITEM          
                                               54 PRINT_NEWLINE       
                                          >>   55 LOAD_CONST               0 (None)
                                               58 RETURN_VALUE
                                  

                                  Cheers (shamy)
                                  Claudia

                                  1 條回覆 最後回覆 回覆 引用 0
                                  • YaronY
                                    Yaron
                                    最後由 編輯

                                    Hello Claudia,

                                    In “one of these days” you’ve written such a beautiful script (I’m sure it is even before testing it).
                                    My esteem has not been diminished at all by that trifle. :)

                                    Thanks again. I appreciate your help.

                                    Have a great night.

                                    1 條回覆 最後回覆 回覆 引用 0
                                    • Scott SumnerS
                                      Scott Sumner
                                      最後由 編輯

                                      @Claudia-Frank said:

                                      if oldLine != editor.lineFromPosition(newPos) and editor.getColumn(newPos) == 0:

                                      I was always taught that if YOU have some question or doubt, somebody reading your code later would also have the same concern, so better to make it explicit with parentheses:

                                      if (oldLine != editor.lineFromPosition(newPos)) and (editor.getColumn(newPos) == 0):

                                      I look forward to trying out the clipboard routine! Thank you, Claudia.

                                      1 條回覆 最後回覆 回覆 引用 1
                                      • Scott SumnerS
                                        Scott Sumner
                                        最後由 編輯

                                        The clipboard routine works well, Claudia, this is so great! Now I just have to write the corresponding ‘set’ version.

                                        1 條回覆 最後回覆 回覆 引用 0
                                        • guy038G
                                          guy038
                                          最後由 guy038 編輯

                                          Hello Yaron, Scoot and Claudia,

                                          I don’t want to disturb, in any way, your interesting discussion, about Python operators precedence ( and other goodies, that I can’t understand, yet ! ) but I, simply, created three macros, that seem to emulate the behaviour that you prefer, Yaron, AFAIK !!

                                          So :

                                          • Close any instance of Notepad++

                                          • Start an OTHER editor than notepad++

                                          • Open, in that editor, the Shortcuts.xml file

                                          • Insert, at the beginning of this file, inside the <Macros> section, the XML text below :

                                              <Macro name="Cut        Current Line w/o EOL" Ctrl="yes" Alt="yes" Shift="no" Key="88">
                                                  <Action type="0" message="2453" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2453" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2345" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2452" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2452" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2177" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2180" wParam="0" lParam="0" sParam="" />
                                              </Macro>
                                              <Macro name="Copy     Current Line w/o EOL" Ctrl="yes" Alt="yes" Shift="no" Key="67">
                                                  <Action type="0" message="2453" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2453" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2345" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2452" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2452" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2178" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2304" wParam="0" lParam="0" sParam="" />
                                              </Macro>
                                              <Macro name="Replace Current line by Clipboard" Ctrl="yes" Alt="yes" Shift="no" Key="86">
                                                  <Action type="0" message="2453" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2453" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2345" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2452" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2452" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2179" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2453" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2453" wParam="0" lParam="0" sParam="" />
                                                  <Action type="0" message="2345" wParam="0" lParam="0" sParam="" />
                                              </Macro>
                                            
                                          • Save the changes, done in the Shortcuts.xml file

                                          • Re-start Notepad++

                                          => In the macros list, you should have three additional entries :

                                          Cut     Current Line w/o EOL       Ctrl + Alt + X
                                          
                                          Copy    Current Line w/o EOL       Ctrl + Alt + C
                                          
                                          Replace Current Line by Clipboard  Ctrl + Alt + V
                                          

                                          Hypotheses :

                                          • I suppose that the Scintilla commands : Home, Alt + Home, Shift + End, Left Arrow and Suppr are the default ones !

                                          • I, also, suppose that the classical Ctrl + X , Ctrl + C and Ctrl + V commands are the default ones, too.

                                          • Finally, the three shortcuts Ctrl + Alt + X, Ctrl + Alt + C and Ctrl + Alt + V should not be used, yet

                                          Notes :

                                          • After execution of the two macros Copy Current Line w/o EOL and Replace Current Line by Clipboard, the caret is moved back, at the very beginning of the current line

                                          • After execution of the macro Cut Current Line w/o EOL, the caret is located, of course, at the very beginning of the next line

                                          • These macros work nice, whatever :

                                            • The current logical line Begins, or not, by some blank characters

                                            • The current logical line is wrapped, or not

                                            • The current logical line is split on several physical lines, preceded, or not, by any indentation

                                            • The present cursor location, in this current logical line

                                            • The EOL characters of the current logical line ( CRLF, LF or CR )

                                            • The current logical line is not terminated by any EOL characters ( case of the very last line of the file ! )


                                          So, let’s consider the simple text, of five lines, below :

                                          First  line to copy
                                          Second line to cut
                                          Third  line to be replaced by the first line
                                          Fourth line to be replaced by the second line
                                          Fifth  line to end
                                          
                                          • Put the cursor, anywhere, in the First line

                                          • Select the macro Macros - Copy Current Line w/o EOL OR hit the Alt + Ctrl + C shortcut

                                          • Put the cursor, anywhere, in the Third line

                                          • Select the macro Macros - Replace Current Line by Clipboard OR hit the Alt + Ctrl + V shortcut

                                          => You should get the modified text, below :

                                          First  line to copy
                                          Second line to cut
                                          First  line to copy
                                          Fourth line to be replaced by the second line
                                          Fifth  line to end
                                          
                                          • Now, put the cursor, anywhere, in the Second line

                                          • Select the macro Macros - Cut Current Line w/o EOL OR hit the Alt + Ctrl + X shortcut

                                          • Put the cursor, anywhere, in the Fourth line

                                          • Select the macro Macros - Replace Current Line by Clipboard OR hit the Alt + Ctrl + V shortcut

                                          => The final result should be :

                                          First  line to copy
                                          First  line to copy
                                          Second line to cut
                                          Fifth  line to end
                                          

                                          Remarks :

                                          • If you use the macro Copy Current Line w/o EOL then put the cursor inside any other line and, finally, use the default CTRL + V command, the current line, while executing the macro, is just inserted, at the new cursor location

                                          • Inversely, if you use the default CTRL + C, to select some lines, then put the cursor inside any other line and, finally, use the macro Replace Current Line by Clipboard, the copied lines will replace the current line, while executing the macro !

                                          • Note, also, that executing, consecutively, several times, any of the two macros Copy Current Line w/o EOL AND/OR Replace Current Line by Clipboard does NOT change the current line at all !!

                                          • However, executing, several times, the macro Cut Current Line w/o EOL deletes the consecutive current lines, keeping the last one, only, in the clipboard, in order to replace any other current line, while executing the Replace Current Line by Clipboard macro

                                          • To end, a very nice trick : if, after using the Copy Current Line w/o EOL OR the Cut Current Line w/o EOL macro, you’re wrong, using the normal paste command ( Ctrl + V ), no panic ! Just execute the Replace Current Line by Clipboard macro ( or Ctrl + Alt + V ), just after :-))

                                          Best Regards,

                                          guy038

                                          P.S. :

                                          You’ve , certainly, noticed that I used, sometimes, in macros, two identical consecutive commands, as Home or Shift + End. These forms are necessary, when the lines are wrapped, in several physical lines and, even more, when a wrapped line is preceded by some leading blank characters !

                                          Claudia FrankC 1 條回覆 最後回覆 回覆 引用 1
                                          • Claudia FrankC
                                            Claudia Frank @guy038
                                            最後由 Claudia Frank 編輯

                                            Hello guy,

                                            what took longer, finding out how to get this solved using macros
                                            or writing this?? ;-)))

                                            Another goody

                                            Cheers
                                            Claudia

                                            1 條回覆 最後回覆 回覆 引用 0
                                            • 第一個貼文
                                              最後的貼文
                                            The Community of users of the Notepad++ text editor.
                                            Powered by NodeBB | Contributors